[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: )
[details=""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.
- This is called dot notation. The syntax is
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 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
;
- 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)
[/details]
[details="Alternate "Hello, world!" and dialog boxes"]
- 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)
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.
[/details]
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")
-@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 usecamelCase
, constants useUPPER_CASE_WITH_UNDERSCORES
, constructors (function that create objects, like cloning; putnew
before the function call) useInitialsCapitalized
, and events usealllowercaseletters
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 returningundefined
. Assigning a property with the value ofundefined
actually still keeps the property there; use thedelete
keyword to actually get rid of it (still treated as beingundefined
, but thein
keyword returnsfalse
for it). - Boolean
There are two Boolean values:true
andfalse
. - 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, useNumber(
BigInt value)
to turn a BigInt to a number (if it's too big, it becomesInfinity
) or useBigInt(
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 alsoInfinity
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: ne
j 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)
\u
nnnn 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()
orvar 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)