JavaScript tutorial (Part 1)

(Reply Here)

[scratchblocks] JavaScript function \( [] @delInput @addInput \) \{ [Test JavaScript in this block!] \} :: operators reporter [/scratchblocks]

(Note: To use JavaScript in Snap!, you will need to enable JavaScript extensions:

Settings -> JavaScript extensions )

"Hello, world!"
console.log("Hello, world!");

Let's break it down:

  • console
    • This is a reference to the object that represents the developer console, which is blocked by school admins.
  • .
    • This is called dot notation. The syntax is object.property. An object is a data structure that has properties, like a sprite. If a property is a function, like what the block above reports, it is called a method.
  • log
    • This is the name of a method of the console object. This writes data to the console.
  • ()
    • Without the parentheses, it gets the method itself as a value, just like a block in a grey ring. The parentheses call the method, just like the run and call blocks.
  • "Hello, world!"
    • This is an argument to the log method. An argument is data that is inputted to a function. Specifically, this is a text string. Strings in JavaScript can be surrounded with "double quotes" or 'single quotes'.
  • ;
    • This ends statements, but they are not required in JavaScript unless you have multiple statements on the same line or a few extra cases. (They are required in Java, which is different from JavaScript)
Alternate "Hello, world!" and dialog boxes
window.alert("Hello, world!");

Since the default object is window, you could just do alert("Hello, world!");
The window has properties and methods about, you guessed it, the current window.
The alert method creates a pop-up dialog box. There are two similar ones: confirm and prompt.
In the JavaScript function reporter in a call block, do return window.confirm("Is Snap! cool?"); or return window.prompt("What is your name?") to see the results. prompt can accept a second argument; see what return window.prompt("What is your name?", "Funtime Foxy"); does.

Comments

In Snap!, you can create program comments by right-clicking the editor then clicking add comment. The comments don't change how the program runs. Comments can be isolated or attached to blocks.
JavaScript has to types of comments: inline and multiline.

//Inline comments start with two slashes and end at the end of the line.
/*Multiline comments start with slash-star,
and end with star-slash.
* is officially called asterisk, but it's a longer word;
it's easier to say star when talking about things like this.*/

Multiline comments don't have to take up multiple lines; in fact, they can be used to insert a comment inside a line!

window./*the window object*/alert/*pop-up box*/(x/*user input*/);

Although that works (if you declared variable x), it makes the code harder to read.

Change the cursor

if you want to change the cursor, use this script (you can change default to "pointer" and "none")
untitled script pic -@SuperSean12
Shorter way to do it: document.body.style.cursor = cursorName; found in this project by @biran4454 - @SnapenilK

NaN

NaN is weird. Its data type is number. It stands for Not a Number. It is never equal to itself. It is not greater than itself, and it is not less than itself. A variable can be not equal to itself if its value is NaN. If NaN is used in a numerical expression, the result of the expression is NaN. 0/0 results in NaN, but it is not equal to NaN. If a string cannot be parsed to a number, it coerces to NaN, but its still not equal to NaN.

Variables
naming

In Snap!, variable names can be any text string.
In JavaScript, they are limited to capital and lowercase letters A-Z, a-z, dollar sign $, and underscore _. Digits 0-9 can be included, but they cannot be first.
Valid names:

  • hello
  • QqQq
  • $_$
  • SnapIsNumber1
  • $5
  • a_b
    Invalid names:
  • Jens Moenig
  • 1stVar
  • 50%
  • if
    Wait, why not if? If is a keyword, a reserved word that means a certain thing in JavaScript
    Usually, variables use camelCase, constants use UPPER_CASE_WITH_UNDERSCORES, constructors (function that create objects, like cloning; put new before the function call) use InitialsCapitalized, and events use alllowercaseletters

Variables work the same way as in Snap. To create one type

let variableName = "variable value"

Text needs to be in quotes " " because if it wasn't then the computer wouldn't know if some code was text or actually an instruction.
You don't have to put numbers in quotes.
Variables can also contain some other data types that will be discussed later
let has limited scope; scope is where in the code the variable is accessible. let can only be used in the same block (should be explained elsewhere). var creates a variable with a bigger scope. If used in a function, the scope is the entire function. Otherwise, it is a global variable.
const has the same scope as let, but it is a constant, which means it cannot be changed.

Some variables are predefined:
window
Object
null
undefined
Number
String
INTL
Math
Array
TypedArray
Functions

Use the function keyword to create your own custom function.
Let's create a function that squares a number.

function getSquare() {}

So far, this function does nothing. Let's give it an input.

function getSquare(number) {}

A variable that represent an input to a function is called a parameter; number is a parameter of the getSquare function. Functions don't need parameters, and they can have multiple parameters separated by commas.

function getSquare(number) {
	return number * number;
}

The return statement allows the interpreter to "return" from the body of the function back to where the function was called. If we put a value or expression after return , the value is used where the function is called.
var n = getSquare(5); n is the square of 5, which is 25.
var m = getSquare(getSquare(2)); m is the square of the square of 2, which is the square of 4, which is 16.
Whenever a function is created, a variable is already created inside it: arguments. It is an object that is similar to an array (to be discussed elsewhere). The arguments object gets all input of the function.
function() {return arguments[0];} This returns the first input of the function (JavaScript and many other programming languages start counting indices of arrays, strings, and other similar data with 0, but Snap! and Scratch start with 1).
Arrow functions:
Usally we use function foo(){} or const foo=function(){}to define a function.We can also use const foo=()=>{}

Generator functions

(Work in Progress)

Async functions

Asynchronous means it runs on a different thread (just like the launch block in Snap!).
(Work in Progress)

Data types
  • undefined
    undefined is used to represent no value. Functions that don't return a value and properties of objects that have not been assigned are treated as returning undefined. Assigning a property with the value of undefined actually still keeps the property there; use the delete keyword to actually get rid of it (still treated as being undefined, but the in keyword returns false for it).
  • Boolean
    There are two Boolean values: true and false.
  • BigInt
    These allow really big integers, even bigger than the biggest Number value. Type an integer (digits 0-9) followed by n. Examples: 0n, -12345n, 999888777666555444333222111000n
    A peculiar thing about BigInts is that they do not work with numbers. I guess that makes sense because they can get really big but numbers can't get that big, and numbers can be decimals. To get around that, use Number(BigInt value) to turn a BigInt to a number (if it's too big, it becomes Infinity) or use BigInt(number value) to turn a number to a BigInt (if it's a decimal, the decimal part is removed)
  • Number
    What you would expect numbers should be. They can be integers with or without .0, decimals, positive with or without +, 0, or negative. There's also Infinity and -Infinity, which aren't really considered numbers in math, but there is a weird number value discussed elsewhere: NaN.
Different bases and scientific notation

These only work with integer numbers and BigInts
If it starts with 0 and has only digits 0-7 or it starts with 0o, it is octal, or base 8
If it starts with 0b, it is binary, or base 2
If it starts with 0x, it is hexadecimal, or base 16 (and can include letters a-f as digits)
Scientific notation: nej where n is number and j is an integer is the same as n * 10**j, or j is number of decimal places to move to the right (negative is move positive amount to the left)

  • String
    A text value; you can surround with "double quotes" or 'apostrophes'; they can be empty ("" or '')
    Strings cannot have a new line (enter) in them unless you put \ before it or are creating a template. A backslash followed by a new line doesn't actually put a new line in the string value, but you can do this:
"First line\n\
Second line"

to have a new line in the value (what it represents) and the literal (what is typed).
Escape sequences:
\n puts a new line in a string
\" puts double quotes in it (not required if surrounded by single quotes)
\' puts an apostrophe in it (not required if surrounded by double quotes)
\\ puts a backslash in it
\b puts a backspace character in it (this makes typewriters move left one character)
\f puts a form feed character in it (this makes typewriters put the paper out)
\r puts a carriage return character in it (this makes typewriters go to the left end of the line)
\t puts a horizontal tab character in it (go to a predetermined horizontal location)
\v puts a vertical tab character in it (go to a predetermined vertical location)
\unnnn takes the four digits nnnn as hexadecimal and puts the character with that code in it
Templates: these are a kind of string surrounded with ``, allow new lines, and you can run an expression inside it with ${the expression}
Example:

var a = 3;
var b = 6;
`Cats have ${a + b} lives` //this equals "Cats have 9 lives"
  • Function
    Functions are discussed elsewhere; to make an anonymous (no-name) function, use
    function() {} just like discussed elsewhere but without the name of the function; must be used as a value (think of it being a gray ring instead of making a block)
    or use () => {}
  • Array
    These are like lists. Surround your values with [ and ], and separate them with ,. Arrays are a type of object, but the properties for the different values are numbers. To access one, put [number or expression that results in a number] after it. The first element in 0. You can use assignment operators to change elements. (Discuss array methods elsewhere)
  • Object
    Objects are discussed elsewhere.
  • Symbol
    Most properties are strings, but this data type can be used for a special kind of property. Symbol() creates a new symbol. Symbol(something) creates a new symbol with a description. Symbols are not automatically converted to strings; you must run its toString() method as if it where an object (e.g. Symbol().toString()or var a = Symbol(); a.toString()) To create or access a property with a symbol, use a computed property name (see the Objects > Computed Property Names section)
Operators
assignment operators

= is just like the set block: put the name of a variable, an object property, or any other data holder on the left side, and a value or expression on the right side to assign to the left side
"+=" is just like the change by block: it adds a number or joins a string to it
"-=" subtracts from it, "*=" multiplies it, "/=" divides it, "**=" raises it to a power
That pattern can be applied to most other operators: the operator followed by = applies it and assigns the result
"++" adds 1; "--" subtracts 1; if they are before (++n), the new value is returned; if they are after (n++), the old value is returned

Example:

var a = 9;
var b = a++;
console.log(b); //prints 9, which is a's value before incrementing
console.log(a); //prints 10, which is a's new value

b = --a; //sets b to a's value after decrementing
console.log(b - a); //prints 0, meaning they are equal
comparison operators

"==" This is loose equality; the operands are changed to the same type, e.g. "5" == 5 is true
"===" This is strict equality; the operands must be the same type to be equal, e.g. "5" === 5 is false
"!=" This is loose inequality; the operands are changed to the same type and returns the opposite of ==
"!==" This is strict inequality; this returns the opposite of ===
"<" is less than, ">" is greater than, "<=" is less than or equal to, ">=" is greater than or equal to

numerical operators

+, -, *, /; they do what you think (add*, subtract, multiply, and divide)
*Both operands must be numbers; otherwise, it joins strings together.
** is for exponentiation (^ is used for bitwise xor); % is for modulo, or remainder after division, or how much more the first number is after a multiple of the second number

bitwise operators

These operate on numbers using their binary representation (0's and 1's). Binary is the base system computers use internally to represent numbers, since computers store data as on's or off's. In base 10/decimal/regular numbers, there are 10 digits used: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. Then to go over the first 9 numbers, you increment the preceding digit (or put a new one if there is none), and start back at 0. So think of that but with only 0 and 1 and you get binary.

Binary, Decimal

0000, 00
0001, 01
0010, 02
0011, 03
0100, 04
0101, 05
0110, 06
0111, 07
1000, 08
1001, 09
1010, 10
1011, 11
1100, 12
1101, 13
1110, 14
1111, 15

& bitwise and; does the logical and operation on each place with 1 being true and 0 being false; a 1 is in a place in the result if the same place in both operands are 1
| bitwise or; does the logical or operation on each place; a 1 is in a place in the result if either operand has a 1 in the same place
^ bitwise xor; a 1 is in a place in the result if only one operand has a 1 in the same place
~ bitwise not; 0's and 1's are exchanged for the other
There are more; can somebody else help with this? ~@SnapenilK

logical operators

"&&" is and, just like the and predicate
"||" is or, just like the or predicate
"!" is not, just like the not predicate

Objects

Objects are data structures with properties, like sprites. You can create your own objects with curly braces.
{} This is an empty object. null is a value that represents no objects or no reference to an object.
If you have variables, you can put them inside the object to create properties with the same names and current values.

var a = 5;
var b = "Hi";
var myObject = {a, b};

To access a property, get an object reference, put a period, and put the property name. It's like the [attribute] of [sprite] block, but the sprite comes first. With the example above:

myObject.a //this returns 5
myObject.b //this returns "Hi"

To set your own value when creating the object, put a colon then the value or an expression after the property name.

var myObject = {
	myNumber: 42,
	myString: "William Afton is Purple Guy",
	myOtherObject: {a: 0, b: 1},
	userInput: window.prompt("Enter a value")
};
myObject.myNumber //this returns 42
myObject.myString //this returns "William Afton is Purple Guy"
myObject.myOtherObject //this returns {a: 0, b: 1}
myObject.myOtherObject.a //this returns 0
myObject.myOtherObject.b //this returns 1
myObject.userInput //this returns whatever the user inputted, or null if the user clicked Cancel
Computed Property Names:

When creating objects, you can put [expression] in place of a property name. The expression is evaluated, converted to a string (if it's not Symbol; can be discussed elsewhere), and that is the property name to create

var myObject = {
["Hello"]: 0,
[prompt("Enter a property name")]: prompt("Enter a value for the property"),
["Property names without [] have the same rules as variable naming,"]: "but [] allows other characters"
};

When accessing properties, you can get rid of the dot and replace the property name with [expression]. The expression is evaluated, converted to a string (if it's not Symbol; can be discussed elsewhere), and that is the property name to access

//In the above example, you can access the first property with any of the following:
myObject.Hello
myObject["Hello"]
myObject["H" + "ello"]
//They all return 0
//The last property must be accessed with:
myObject["Property names without [] have the same rules as variable naming,"]

To reassign properties, use the assignment operators.

var myObj = {a: "Hi!"}; //myObj.a is "Hi!"
myObj.a = "Another string"; //myObj.a is now "Another string"
//Properties can be reassigned the same type (as above) or a different type (as below)
myObj.a = 0; //myObj.a is now 0
myObj.a++; //same as myObj.a += 1; myObj.a is now 1
myObj.a += 5; //same as myObj.a = myObj.a + 5; myObj.a is now 6
myObj.a--; //myObj.a is now 5
myObj.b = "I can create new properties!" //myObj.b is created and is a string
delete myObj.a; //the delete keyword can be used to remove properties from objects
Common Errors
Uncaught SyntaxError: Unexpected identifier

Incorrect:

fo o="foo"
``
Correct:
```javascript
fo,o="foo"
Uncaught SyntaxError: Invalid or unexpected token

Incorrect:

17bar="foo"

Correct:

bar="foo"
Movement in Snap

idk, somebody else add it
Umm... @SuperSean12, what would go here? - @SnapenilK
moving sprites with java script - @SuperSean12
this.forward(10) - @programmer_user
Note: that moves the sprite forward (or backward if negative) based on its direction (the move _ steps block)

APIs
Canvas

You do not need to know this.instead use processing.js.
^ That is not helpful. ~SnapenilK

Fetch

The Fetch API allows you to access web data from JavaScript.
Here's an example:

fetch("https://snap.berkeley.edu/") //fetch the Snap! homepage
	.then ((response) => response.text()) //get the text of the response
	.then ((text) => {
		/*do whatever you want with the text!
		here, the data is logged into the console*/
		console.log(text);
	});

You can get the JSON data of responses, as an object:

//NOTE: the following code will only work on Scratch, because of CORS
//the same applies to the previous example with Snap!, but I didn't mention it there because you'd most likely be running it in the Snap! editor
fetch("https://api.scratch.mit.edu/users/griffpatch/messages/count") //fetch the message count of griffpatch on Scratch
	.then ((response) => response.json()) //get the JSON of the response as an object
	.then ((json) => {
			console.log(json); //the whole response
			console.log(json.count); //just the message count
	});

Note: Due to CORS, some websites may not be able to be acccessed from outside themselves. e.g you can't access google.com from snap.berkeley.edu, or snap.berkeley.edu from forum.snap.berkeley.edu.
Additionally, there is XMLHttpRequest, which is a lot more complicated and won't be covered here.

Asynchronous threads ("launch" in JavaScript; timeouts and intervals)

window.setTimeout() (or just setTimeout() because window is the default object)
This function returns a number, which is the ID of this specific timeout.
The first argument of it is a function (or a string of text representing JS code to run), and the optional second argument is a number. With the second argument, it waits that number of milliseconds (1000 for 1 second) before running the function/code; without it, the function/code is run as soon as possible.
If the first argument is a function, then you can pass arguments (inputs) to it after the second argument.

setTimeout(alert, 3000, "Hello, world!");

After three seconds, you should get a pop-up with Hello, world!


window.setInterval() (or just setInterval())
This function does the same thing as setTimeout() but it runs it in a loop; setTimeout() does it once (unless cleared) and setInterval() does it forever (until cleared)


window.clearTimeout() (or just clearTimeout())
window.clearInterval() (or just clearInterval())
A funny thing is that both of them can clear timeouts and intervals (clearTimeout() can clear timeouts as well as intervals, and the same for clearInterval()).
Run it with one argument: the number that was returned by setTimeout() or setInterval().
This cancels a timeout before it runs (it does nothing if the timeout already ran) and it stops an interval.

Promise: more async

(Work in Progress)

6 Likes

@FUNTIME_FOXY101 here's the JavaScript tutorial you asked for
@snapenilk this seems great, will contribute to it tomorrow

Yep, I am already trying out the "Change the cursor" JS function. :D

this can go in the #how-to topic

Do some predefined objects.

We should make some guidelines so that this doesn't turn into edit wars on Wikipedia.
@bh


1 Like

ok

console.log("Woaj, this JS tutorial already got so many edits!");

Does that work the same way as console.log("Hello, world!");?

1 Like

I got edit conflict when you wher editing.

yes

Yeah, good idea. We should.

Yay! :D

So this is your first taste of JS :DDDDD

Hmmm, maybe we should let each other know when we are editing, and when the person who is editing is done, they should reply to it to let us know, and then someone else will edit?

Yeah, I'm so happy! :>

Or is that my hyperness talking? XD

No one is editing, someone (one person) can edit now? (I had to edit to see if someone was editing, and then I pressed cancel when I was done checking.)

Mutex!

What's that?

Hey, someone should make a JavaScript tutorial project with clickable JSFunction blocks.

i added that :)