2020-08-05 10:37:11 +03:00
[38;5;246;03m// Single-line comments start with two slashes. [39;00m
[38;5;246;03m/* Multiline comments start with slash-star, [39;00m
[38;5;246;03m and end with star-slash */ [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Statements can be terminated by ; [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mdoStuff [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ... but they don't have to be, as semicolons are automatically inserted [39;00m
[38;5;246;03m// wherever there's a newline, except in certain cases. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mdoStuff [39m [38;5;252m( [39m [38;5;252m) [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Because those cases can cause unexpected results, we'll keep on using [39;00m
[38;5;246;03m// semicolons in this guide. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m/////////////////////////////////// [39;00m
[38;5;246;03m// 1. Numbers, Strings and Operators [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// JavaScript has one number type (which is a 64-bit IEEE 754 double). [39;00m
[38;5;246;03m// Doubles have a 52-bit mantissa, which is enough to store integers [39;00m
[38;5;246;03m// up to about 9✕10¹⁵ precisely. [39;00m
[38;5;67m3 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 3 [39;00m
[38;5;67m1.5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 1.5 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Some basic arithmetic works as you'd expect. [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 2 [39;00m
[38;5;67m0.1 [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;67m0.2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 0.30000000000000004 [39;00m
[38;5;67m8 [39m [38;5;252m [39m [38;5;252m- [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 7 [39;00m
[38;5;67m10 [39m [38;5;252m [39m [38;5;252m* [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 20 [39;00m
[38;5;67m35 [39m [38;5;252m [39m [38;5;252m/ [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 7 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Including uneven division. [39;00m
[38;5;67m5 [39m [38;5;252m [39m [38;5;252m/ [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 2.5 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// And modulo division. [39;00m
[38;5;67m10 [39m [38;5;252m [39m [38;5;252m% [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 0 [39;00m
[38;5;67m30 [39m [38;5;252m [39m [38;5;252m% [39m [38;5;252m [39m [38;5;67m4 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 2 [39;00m
[38;5;67m18.5 [39m [38;5;252m [39m [38;5;252m% [39m [38;5;252m [39m [38;5;67m7 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 4.5 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Bitwise operations also work; when you perform a bitwise operation your float [39;00m
[38;5;246;03m// is converted to a signed int *up to* 32 bits. [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m<< [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 4 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Precedence is enforced with parentheses. [39;00m
[38;5;252m( [39m [38;5;67m1 [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;67m3 [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m* [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 8 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// There are three special not-a-real-number values: [39;00m
[38;5;70;01mInfinity [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// result of e.g. 1/0 [39;00m
[38;5;252m- [39m [38;5;70;01mInfinity [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// result of e.g. -1/0 [39;00m
[38;5;70;01mNaN [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// result of e.g. 0/0, stands for 'Not a Number' [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// There's also a boolean type. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mtrue [39;00m [38;5;252m; [39m
[38;5;70;01mfalse [39;00m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Strings are created with ' or ". [39;00m
2019-02-17 16:03:46 +03:00
[38;5;214m'abc' [39m [38;5;252m; [39m
[38;5;214m"Hello, world" [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Negation uses the ! symbol [39;00m
[38;5;252m! [39m [38;5;70;01mtrue [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
[38;5;252m! [39m [38;5;70;01mfalse [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Equality is === [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
[38;5;67m2 [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Inequality is !== [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m!== [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
[38;5;67m2 [39m [38;5;252m [39m [38;5;252m!== [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// More comparisons [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m< [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
[38;5;67m1 [39m [38;5;252m [39m [38;5;252m> [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
[38;5;67m2 [39m [38;5;252m [39m [38;5;252m<= [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
[38;5;67m2 [39m [38;5;252m [39m [38;5;252m>= [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Strings are concatenated with + [39;00m
[38;5;214m"Hello " [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;214m"world!" [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello world!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ... which works with more than just strings [39;00m
[38;5;214m"1, 2, " [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;67m3 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "1, 2, 3" [39;00m
[38;5;214m"Hello " [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;214m"world" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m"!" [39m [38;5;252m] [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello world,!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// and are compared with < and > [39;00m
[38;5;214m"a" [39m [38;5;252m [39m [38;5;252m< [39m [38;5;252m [39m [38;5;214m"b" [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Type coercion is performed for comparisons with double equals... [39;00m
[38;5;214m"5" [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
[38;5;70;01mnull [39;00m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;70;01mundefined [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ...unless you use === [39;00m
[38;5;214m"5" [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
[38;5;70;01mnull [39;00m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;70;01mundefined [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ...which can result in some weird behaviour... [39;00m
[38;5;67m13 [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252m! [39m [38;5;67m0 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// 14 [39;00m
[38;5;214m"13" [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252m! [39m [38;5;67m0 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// '13true' [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// You can access characters in a string with `charAt` [39;00m
[38;5;214m"This is a string" [39m [38;5;252m. [39m [38;5;252mcharAt [39m [38;5;252m( [39m [38;5;67m0 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 'T' [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ...or use `substring` to get larger pieces. [39;00m
[38;5;214m"Hello world" [39m [38;5;252m. [39m [38;5;252msubstring [39m [38;5;252m( [39m [38;5;67m0 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// `length` is a property, so don't use (). [39;00m
[38;5;214m"Hello" [39m [38;5;252m. [39m [38;5;252mlength [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 5 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// There's also `null` and `undefined`. [39;00m
[38;5;70;01mnull [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// used to indicate a deliberate non-value [39;00m
[38;5;70;01mundefined [39;00m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// used to indicate a value is not currently present (although [39;00m
[38;5;252m [39m [38;5;246;03m// `undefined` is actually a value itself) [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy. [39;00m
[38;5;246;03m// Note that 0 is falsy and "0" is truthy, even though 0 == "0". [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m/////////////////////////////////// [39;00m
[38;5;246;03m// 2. Variables, Arrays and Objects [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Variables are declared with the `var` keyword. JavaScript is dynamically [39;00m
[38;5;246;03m// typed, so you don't need to specify type. Assignment uses a single `=` [39;00m
[38;5;246;03m// character. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252msomeVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// If you leave the var keyword off, you won't get an error... [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252msomeOtherVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ...but your variable will be created in the global scope, not in the scope [39;00m
[38;5;246;03m// you defined it in. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Variables declared without being assigned to are set to undefined. [39;00m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252msomeThirdVar [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = undefined [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// If you want to declare a couple of variables, then you could use a comma [39;00m
[38;5;246;03m// separator [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252msomeFourthVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252msomeFifthVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m4 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// There's shorthand for performing math operations on variables: [39;00m
[38;5;252msomeVar [39m [38;5;252m [39m [38;5;252m+= [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// equivalent to someVar = someVar + 5; someVar is 10 now [39;00m
[38;5;252msomeVar [39m [38;5;252m [39m [38;5;252m*= [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// now someVar is 100 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// and an even-shorter-hand for adding or subtracting 1 [39;00m
[38;5;252msomeVar [39m [38;5;252m++ [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// now someVar is 101 [39;00m
[38;5;252msomeVar [39m [38;5;252m-- [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// back to 100 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Arrays are ordered lists of values, of any type. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyArray [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;214m"Hello" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m45 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;70;01mtrue [39;00m [38;5;252m] [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Their members can be accessed using the square-brackets subscript syntax. [39;00m
[38;5;246;03m// Array indices start at zero. [39;00m
[38;5;252mmyArray [39m [38;5;252m[ [39m [38;5;67m1 [39m [38;5;252m] [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 45 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Arrays are mutable and of variable length. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252mpush [39m [38;5;252m( [39m [38;5;214m"World" [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252mlength [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 4 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Add/Modify at specific index [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyArray [39m [38;5;252m[ [39m [38;5;67m3 [39m [38;5;252m] [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"Hello" [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Add and remove element from front or back end of an array [39;00m
[38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252munshift [39m [38;5;252m( [39m [38;5;67m3 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// Add as the first element [39;00m
[38;5;252msomeVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252mshift [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// Remove first element and return it [39;00m
[38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252mpush [39m [38;5;252m( [39m [38;5;67m3 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// Add as the last element [39;00m
[38;5;252msomeVar [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mmyArray [39m [38;5;252m. [39m [38;5;252mpop [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// Remove last element and return it [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Join all elements of an array with semicolon [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyArray0 [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;67m32 [39m [38;5;252m, [39m [38;5;70;01mfalse [39;00m [38;5;252m, [39m [38;5;214m"js" [39m [38;5;252m, [39m [38;5;67m12 [39m [38;5;252m, [39m [38;5;67m56 [39m [38;5;252m, [39m [38;5;67m90 [39m [38;5;252m] [39m [38;5;252m; [39m
2020-08-06 08:28:08 +03:00
[38;5;252mmyArray0 [39m [38;5;252m. [39m [38;5;252mjoin [39m [38;5;252m( [39m [38;5;214m";" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "32;false;js;12;56;90" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Get subarray of elements from index 1 (include) to 4 (exclude) [39;00m
[38;5;252mmyArray0 [39m [38;5;252m. [39m [38;5;252mslice [39m [38;5;252m( [39m [38;5;67m1 [39m [38;5;252m, [39m [38;5;67m4 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = [false,"js",12] [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Remove 4 elements starting from index 2, and insert there strings [39;00m
[38;5;246;03m// "hi","wr" and "ld"; return removed subarray [39;00m
[38;5;252mmyArray0 [39m [38;5;252m. [39m [38;5;252msplice [39m [38;5;252m( [39m [38;5;67m2 [39m [38;5;252m, [39m [38;5;67m4 [39m [38;5;252m, [39m [38;5;214m"hi" [39m [38;5;252m, [39m [38;5;214m"wr" [39m [38;5;252m, [39m [38;5;214m"ld" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = ["js",12,56,90] [39;00m
[38;5;246;03m// myArray0 === [32,false,"hi","wr","ld"] [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// JavaScript's objects are equivalent to "dictionaries" or "maps" in other [39;00m
[38;5;246;03m// languages: an unordered collection of key-value pairs. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m [38;5;252mkey1 [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m"Hello" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252mkey2 [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m"World" [39m [38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Keys are strings, but quotes aren't required if they're a valid [39;00m
[38;5;246;03m// JavaScript identifier. Values can be any type. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m [38;5;252mmyKey [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m"myValue" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m"my other key" [39m [38;5;252m: [39m [38;5;252m [39m [38;5;67m4 [39m [38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Object attributes can also be accessed using the subscript syntax, [39;00m
[38;5;252mmyObj [39m [38;5;252m[ [39m [38;5;214m"my other key" [39m [38;5;252m] [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 4 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// ... or using the dot syntax, provided the key is a valid identifier. [39;00m
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyKey [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "myValue" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Objects are mutable; values can be changed and new keys added. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyThirdKey [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mtrue [39;00m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// If you try to access a value that's not yet set, you'll get undefined. [39;00m
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyFourthKey [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = undefined [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m/////////////////////////////////// [39;00m
[38;5;246;03m// 3. Logic and Control Structures [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The `if` structure works as you'd expect. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mcount [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m1 [39m [38;5;252m; [39m
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mcount [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;67m3 [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// evaluated if count is 3 [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m [38;5;252m [39m [38;5;70;01melse [39;00m [38;5;252m [39m [38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mcount [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;67m4 [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// evaluated if count is 4 [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m [38;5;252m [39m [38;5;70;01melse [39;00m [38;5;252m [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// evaluated if it's not either 3 or 4 [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// As does `while`. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mwhile [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mtrue [39;00m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// An infinite loop! [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Do-while loops are like while loops, except they always run at least once. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252minput [39m [38;5;252m; [39m
[38;5;70;01mdo [39;00m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252minput [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mgetInput [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m [39m [38;5;70;01mwhile [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252m! [39m [38;5;252misValid [39m [38;5;252m( [39m [38;5;252minput [39m [38;5;252m) [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The `for` loop is the same as C and Java: [39;00m
[38;5;246;03m// initialization; continue condition; iteration. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m0 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m< [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mi [39m [38;5;252m++ [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// will run 5 times [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Breaking out of labeled loops is similar to Java [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mouter [39m [38;5;252m: [39m
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m0 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m< [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mi [39m [38;5;252m++ [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m0 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mj [39m [38;5;252m [39m [38;5;252m< [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252mj [39m [38;5;252m++ [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m [39m [38;5;252m&& [39m [38;5;252m [39m [38;5;252mj [39m [38;5;252m [39m [38;5;252m== [39m [38;5;67m5 [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mbreak [39;00m [38;5;252m [39m [38;5;252mouter [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// breaks out of outer loop instead of only the inner one [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The for/in statement allows iteration over properties of an object. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mdescription [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"" [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mperson [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m [38;5;252mfname [39m [38;5;252m: [39m [38;5;214m"Paul" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252mlname [39m [38;5;252m: [39m [38;5;214m"Ken" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252mage [39m [38;5;252m: [39m [38;5;67m18 [39m [38;5;252m} [39m [38;5;252m; [39m
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mx [39m [38;5;252m [39m [38;5;70;01min [39;00m [38;5;252m [39m [38;5;252mperson [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mdescription [39m [38;5;252m [39m [38;5;252m+= [39m [38;5;252m [39m [38;5;252mperson [39m [38;5;252m[ [39m [38;5;252mx [39m [38;5;252m] [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;214m" " [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m} [39m [38;5;252m [39m [38;5;246;03m// description = 'Paul Ken 18 ' [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The for/of statement allows iteration over iterable objects (including the built-in String, [39;00m
[38;5;246;03m// Array, e.g. the Array-like arguments or NodeList objects, TypedArray, Map and Set, [39;00m
[38;5;246;03m// and user-defined iterables). [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyPets [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"" [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mpets [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;214m"cat" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m"dog" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m"hamster" [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m"hedgehog" [39m [38;5;252m] [39m [38;5;252m; [39m
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mpet [39m [38;5;252m [39m [38;5;70;01mof [39;00m [38;5;252m [39m [38;5;252mpets [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyPets [39m [38;5;252m [39m [38;5;252m+= [39m [38;5;252m [39m [38;5;252mpet [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;214m" " [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m} [39m [38;5;252m [39m [38;5;246;03m// myPets = 'cat dog hamster hedgehog ' [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// && is logical and, || is logical or [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mhouse [39m [38;5;252m. [39m [38;5;252msize [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;214m"big" [39m [38;5;252m [39m [38;5;252m&& [39m [38;5;252m [39m [38;5;252mhouse [39m [38;5;252m. [39m [38;5;252mcolour [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;214m"blue" [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mhouse [39m [38;5;252m. [39m [38;5;252mcontains [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"bear" [39m [38;5;252m; [39m
[38;5;252m} [39m
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mcolour [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;214m"red" [39m [38;5;252m [39m [38;5;252m|| [39m [38;5;252m [39m [38;5;252mcolour [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;214m"blue" [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// colour is either red or blue [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// && and || "short circuit", which is useful for setting default values. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mname [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252motherName [39m [38;5;252m [39m [38;5;252m|| [39m [38;5;252m [39m [38;5;214m"default" [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The `switch` statement checks for equality with `===`. [39;00m
[38;5;246;03m// Use 'break' after each case [39;00m
[38;5;246;03m// or the cases after the correct one will be executed too. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mgrade [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m'B' [39m [38;5;252m; [39m
[38;5;70;01mswitch [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mgrade [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mcase [39;00m [38;5;252m [39m [38;5;214m'A' [39m [38;5;252m: [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;214m"Great job" [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mbreak [39;00m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mcase [39;00m [38;5;252m [39m [38;5;214m'B' [39m [38;5;252m: [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;214m"OK job" [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mbreak [39;00m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mcase [39;00m [38;5;252m [39m [38;5;214m'C' [39m [38;5;252m: [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;214m"You can do better" [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mbreak [39;00m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mdefault [39;00m [38;5;252m: [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;214m"Oy vey" [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;70;01mbreak [39;00m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m/////////////////////////////////// [39;00m
[38;5;246;03m// 4. Functions, Scope and Closures [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// JavaScript functions are declared with the `function` keyword. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;252mthing [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;252mthing [39m [38;5;252m. [39m [38;5;252mtoUpperCase [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;214m"foo" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "FOO" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Note that the value to be returned must start on the same line as the [39;00m
[38;5;246;03m// `return` keyword, otherwise you'll always return `undefined` due to [39;00m
[38;5;246;03m// automatic semicolon insertion. Watch out for this when using Allman style. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;246;03m// <- semicolon automatically inserted here [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;252m{ [39m [38;5;252mthisIsAn [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m'object literal' [39m [38;5;252m} [39m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = undefined [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// JavaScript functions are first class objects, so they can be reassigned to [39;00m
[38;5;246;03m// different variable names and passed to other functions as arguments - for [39;00m
[38;5;246;03m// example, when supplying an event handler: [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// this code will be called in 5 seconds' time [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
[38;5;252msetTimeout [39m [38;5;252m( [39m [38;5;252mmyFunction [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m5000 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Note: setTimeout isn't part of the JS language, but is provided by browsers [39;00m
[38;5;246;03m// and Node.js. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Another function provided by browsers is setInterval [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252mmyFunction [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// this code will be called every 5 seconds [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
[38;5;252msetInterval [39m [38;5;252m( [39m [38;5;252mmyFunction [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m5000 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Function objects don't even have to be declared with a name - you can write [39;00m
[38;5;246;03m// an anonymous function definition directly into the arguments of another. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252msetTimeout [39m [38;5;252m( [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// this code will be called in 5 seconds' time [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m5000 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// JavaScript has function scope; functions get their own scope but other blocks [39;00m
[38;5;246;03m// do not. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mtrue [39;00m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mi [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;252mi [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 5 - not undefined as you'd expect in a block-scoped language [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// This has led to a common pattern of "immediately-executing anonymous [39;00m
[38;5;246;03m// functions", which prevent temporary variables from leaking into the global [39;00m
[38;5;246;03m// scope. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m( [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mtemporary [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// We can access the global scope by assigning to the "global object", which [39;00m
[38;5;252m [39m [38;5;246;03m// in a web browser is always `window`. The global object may have a [39;00m
[38;5;252m [39m [38;5;246;03m// different name in non-browser environments such as Node.js. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;31mwindow [39m [38;5;252m. [39m [38;5;252mpermanent [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m10 [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m) [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mtemporary [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// raises ReferenceError [39;00m
[38;5;252mpermanent [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 10 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// One of JavaScript's most powerful features is closures. If a function is [39;00m
[38;5;246;03m// defined inside another function, the inner function has access to all the [39;00m
[38;5;246;03m// outer function's variables, even after the outer function exits. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252msayHelloInFiveSeconds [39m [38;5;252m( [39m [38;5;252mname [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mprompt [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"Hello, " [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252mname [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;214m"!" [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// Inner functions are put in the local scope by default, as if they were [39;00m
[38;5;252m [39m [38;5;246;03m// declared with `var`. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252minner [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252malert [39m [38;5;252m( [39m [38;5;252mprompt [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m [39m [38;5;252msetTimeout [39m [38;5;252m( [39m [38;5;252minner [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m5000 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// setTimeout is asynchronous, so the sayHelloInFiveSeconds function will [39;00m
[38;5;252m [39m [38;5;246;03m// exit immediately, and setTimeout will call inner afterwards. However, [39;00m
[38;5;252m [39m [38;5;246;03m// because inner is "closed over" sayHelloInFiveSeconds, inner still has [39;00m
[38;5;252m [39m [38;5;246;03m// access to the `prompt` variable when it is finally called. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;252msayHelloInFiveSeconds [39m [38;5;252m( [39m [38;5;214m"Adam" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// will open a popup with "Hello, Adam!" in 5s [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m/////////////////////////////////// [39;00m
[38;5;246;03m// 5. More about Objects; Constructors and Prototypes [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Objects can contain functions. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyFunc [39m [38;5;252m: [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;214m"Hello world!" [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyFunc [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello world!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// When functions attached to an object are called, they can access the object [39;00m
[38;5;246;03m// they're attached to using the `this` keyword. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyString [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m"Hello world!" [39m [38;5;252m, [39m
[38;5;252m [39m [38;5;252mmyFunc [39m [38;5;252m: [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyString [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyFunc [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello world!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// What this is set to has to do with how the function is called, not where [39;00m
[38;5;246;03m// it's defined. So, our function doesn't work if it isn't called in the [39;00m
[38;5;246;03m// context of the object. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyFunc [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyFunc [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyFunc [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = undefined [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Inversely, a function can be assigned to the object and gain access to it [39;00m
[38;5;246;03m// through `this`, even if it wasn't attached when it was defined. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyOtherFunc [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyString [39m [38;5;252m. [39m [38;5;252mtoUpperCase [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyOtherFunc [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mmyOtherFunc [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyOtherFunc [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "HELLO WORLD!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// We can also specify a context for a function to execute in when we invoke it [39;00m
[38;5;246;03m// using `call` or `apply`. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252manotherFunc [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252ms [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyString [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252ms [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252manotherFunc [39m [38;5;252m. [39m [38;5;252mcall [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m, [39m [38;5;252m [39m [38;5;214m" And Hello Moon!" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello World! And Hello Moon!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The `apply` function is nearly identical, but takes an array for an argument [39;00m
[38;5;246;03m// list. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;252manotherFunc [39m [38;5;252m. [39m [38;5;252mapply [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;214m" And Hello Sun!" [39m [38;5;252m] [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello World! And Hello Sun!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// This is useful when working with a function that accepts a sequence of [39;00m
[38;5;246;03m// arguments and you want to pass an array. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;31mMath [39m [38;5;252m. [39m [38;5;252mmin [39m [38;5;252m( [39m [38;5;67m42 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m6 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m27 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 6 [39;00m
[38;5;31mMath [39m [38;5;252m. [39m [38;5;252mmin [39m [38;5;252m( [39m [38;5;252m[ [39m [38;5;67m42 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m6 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m27 [39m [38;5;252m] [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = NaN (uh-oh!) [39;00m
[38;5;31mMath [39m [38;5;252m. [39m [38;5;252mmin [39m [38;5;252m. [39m [38;5;252mapply [39m [38;5;252m( [39m [38;5;31mMath [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252m[ [39m [38;5;67m42 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m6 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m27 [39m [38;5;252m] [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 6 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// But, `call` and `apply` are only temporary. When we want it to stick, we can [39;00m
[38;5;246;03m// use `bind`. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mboundFunc [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252manotherFunc [39m [38;5;252m. [39m [38;5;252mbind [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mboundFunc [39m [38;5;252m( [39m [38;5;214m" And Hello Saturn!" [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "Hello World! And Hello Saturn!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// `bind` can also be used to partially apply (curry) a function. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mproduct [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252ma [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252mb [39m [38;5;252m) [39m [38;5;252m{ [39m [38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;252ma [39m [38;5;252m [39m [38;5;252m* [39m [38;5;252m [39m [38;5;252mb [39m [38;5;252m; [39m [38;5;252m [39m [38;5;252m} [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mdoubler [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mproduct [39m [38;5;252m. [39m [38;5;252mbind [39m [38;5;252m( [39m [38;5;70;01mthis [39;00m [38;5;252m, [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mdoubler [39m [38;5;252m( [39m [38;5;67m8 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 16 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// When you call a function with the `new` keyword, a new object is created, and [39;00m
[38;5;246;03m// made available to the function via the `this` keyword. Functions designed to be [39;00m
[38;5;246;03m// called like that are called constructors. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mMyConstructor [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyNumber [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyNewObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mnew [39;00m [38;5;252m [39m [38;5;252mMyConstructor [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = {myNumber: 5} [39;00m
[38;5;252mmyNewObj [39m [38;5;252m. [39m [38;5;252mmyNumber [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 5 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Unlike most other popular object-oriented languages, JavaScript has no [39;00m
[38;5;246;03m// concept of 'instances' created from 'class' blueprints; instead, JavaScript [39;00m
[38;5;246;03m// combines instantiation and inheritance into a single concept: a 'prototype'. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Every JavaScript object has a 'prototype'. When you go to access a property [39;00m
[38;5;246;03m// on an object that doesn't exist on the actual object, the interpreter will [39;00m
[38;5;246;03m// look at its prototype. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Some JS implementations let you access an object's prototype on the magic [39;00m
[38;5;246;03m// property `__proto__`. While this is useful for explaining prototypes it's not [39;00m
[38;5;246;03m// part of the standard; we'll get to standard ways of using prototypes later. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyString [39m [38;5;252m: [39m [38;5;252m [39m [38;5;214m"Hello world!" [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyPrototype [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmeaningOfLife [39m [38;5;252m: [39m [38;5;252m [39m [38;5;67m42 [39m [38;5;252m, [39m
[38;5;252m [39m [38;5;252mmyFunc [39m [38;5;252m: [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyString [39m [38;5;252m. [39m [38;5;252mtoLowerCase [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252m__proto__ [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mmyPrototype [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmeaningOfLife [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 42 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// This works for functions, too. [39;00m
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyFunc [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "hello world!" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Of course, if your property isn't on your prototype, the prototype's [39;00m
[38;5;246;03m// prototype is searched, and so on. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyPrototype [39m [38;5;252m. [39m [38;5;252m__proto__ [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyBoolean [39m [38;5;252m: [39m [38;5;252m [39m [38;5;70;01mtrue [39;00m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmyBoolean [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// There's no copying involved here; each object stores a reference to its [39;00m
[38;5;246;03m// prototype. This means we can alter the prototype and our changes will be [39;00m
[38;5;246;03m// reflected everywhere. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyPrototype [39m [38;5;252m. [39m [38;5;252mmeaningOfLife [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m43 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmeaningOfLife [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 43 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The for/in statement allows iteration over properties of an object, [39;00m
[38;5;246;03m// walking up the prototype chain until it sees a null prototype. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mx [39m [38;5;252m [39m [38;5;70;01min [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m[ [39m [38;5;252mx [39m [38;5;252m] [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m///prints: [39;00m
[38;5;246;03m// Hello world! [39;00m
[38;5;246;03m// 43 [39;00m
[38;5;246;03m// [Function: myFunc] [39;00m
[38;5;246;03m// true [39;00m
[38;5;246;03m// To only consider properties attached to the object itself [39;00m
[38;5;246;03m// and not its prototypes, use the `hasOwnProperty()` check. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mfor [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mx [39m [38;5;252m [39m [38;5;70;01min [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mhasOwnProperty [39m [38;5;252m( [39m [38;5;252mx [39m [38;5;252m) [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mconsole [39m [38;5;252m. [39m [38;5;252mlog [39m [38;5;252m( [39m [38;5;252mmyObj [39m [38;5;252m[ [39m [38;5;252mx [39m [38;5;252m] [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m///prints: [39;00m
[38;5;246;03m// Hello world! [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// We mentioned that `__proto__` was non-standard, and there's no standard way to [39;00m
[38;5;246;03m// change the prototype of an existing object. However, there are two ways to [39;00m
[38;5;246;03m// create a new object with a given prototype. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The first is Object.create, which is a recent addition to JS, and therefore [39;00m
[38;5;246;03m// not available in all implementations yet. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;31mObject [39m [38;5;252m. [39m [38;5;252mcreate [39m [38;5;252m( [39m [38;5;252mmyPrototype [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyObj [39m [38;5;252m. [39m [38;5;252mmeaningOfLife [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 43 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// The second way, which works anywhere, has to do with constructors. [39;00m
[38;5;246;03m// Constructors have a property called prototype. This is *not* the prototype of [39;00m
[38;5;246;03m// the constructor function itself; instead, it's the prototype that new objects [39;00m
[38;5;246;03m// are given when they're created with that constructor and the new keyword. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mMyConstructor [39m [38;5;252m. [39m [38;5;252mprototype [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;252mmyNumber [39m [38;5;252m: [39m [38;5;252m [39m [38;5;67m5 [39m [38;5;252m, [39m
[38;5;252m [39m [38;5;252mgetMyNumber [39m [38;5;252m: [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mmyNumber [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyNewObj2 [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mnew [39;00m [38;5;252m [39m [38;5;252mMyConstructor [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyNewObj2 [39m [38;5;252m. [39m [38;5;252mgetMyNumber [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 5 [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252mmyNewObj2 [39m [38;5;252m. [39m [38;5;252mmyNumber [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m6 [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyNewObj2 [39m [38;5;252m. [39m [38;5;252mgetMyNumber [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 6 [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Built-in types like strings and numbers also have constructors that create [39;00m
[38;5;246;03m// equivalent wrapper objects. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyNumber [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m12 [39m [38;5;252m; [39m
[38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mmyNumberObj [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mnew [39;00m [38;5;252m [39m [38;5;31mNumber [39m [38;5;252m( [39m [38;5;67m12 [39m [38;5;252m) [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252mmyNumber [39m [38;5;252m [39m [38;5;252m== [39m [38;5;252m [39m [38;5;252mmyNumberObj [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = true [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// Except, they aren't exactly equivalent. [39;00m
[38;5;70;01mtypeof [39;00m [38;5;252m [39m [38;5;252mmyNumber [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 'number' [39;00m
[38;5;70;01mtypeof [39;00m [38;5;252m [39m [38;5;252mmyNumberObj [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = 'object' [39;00m
[38;5;252mmyNumber [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;252mmyNumberObj [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = false [39;00m
2019-02-17 16:03:46 +03:00
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;67m0 [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// This code won't execute, because 0 is falsy. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;70;01mnew [39;00m [38;5;252m [39m [38;5;31mNumber [39m [38;5;252m( [39m [38;5;67m0 [39m [38;5;252m) [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// This code will execute, because wrapped numbers are objects, and objects [39;00m
[38;5;252m [39m [38;5;246;03m// are always truthy. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m} [39m
2020-08-05 10:37:11 +03:00
[38;5;246;03m// However, the wrapper objects and the regular builtins share a prototype, so [39;00m
[38;5;246;03m// you can actually add functionality to a string, for instance. [39;00m
2019-02-17 16:03:46 +03:00
[38;5;31mString [39m [38;5;252m. [39m [38;5;252mprototype [39m [38;5;252m. [39m [38;5;252mfirstCharacter [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mthis [39;00m [38;5;252m. [39m [38;5;252mcharAt [39m [38;5;252m( [39m [38;5;67m0 [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;214m"abc" [39m [38;5;252m. [39m [38;5;252mfirstCharacter [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// = "a" [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// This fact is often used in "polyfilling", which is implementing newer [39;00m
[38;5;246;03m// features of JavaScript in an older subset of JavaScript, so that they can be [39;00m
[38;5;246;03m// used in older environments such as outdated browsers. [39;00m
2019-02-17 16:03:46 +03:00
2020-08-05 10:37:11 +03:00
[38;5;246;03m// For instance, we mentioned that Object.create isn't yet available in all [39;00m
[38;5;246;03m// implementations, but we can still use it with this polyfill: [39;00m
[38;5;70;01mif [39;00m [38;5;252m [39m [38;5;252m( [39m [38;5;31mObject [39m [38;5;252m. [39m [38;5;252mcreate [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;70;01mundefined [39;00m [38;5;252m) [39m [38;5;252m{ [39m [38;5;252m [39m [38;5;246;03m// don't overwrite it if it exists [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;31mObject [39m [38;5;252m. [39m [38;5;252mcreate [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252mproto [39m [38;5;252m) [39m [38;5;252m{ [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// make a temporary constructor with the right prototype [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;70;01mvar [39;00m [38;5;252m [39m [38;5;252mConstructor [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;70;01mfunction [39;00m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m{ [39m [38;5;252m} [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252mConstructor [39m [38;5;252m. [39m [38;5;252mprototype [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252mproto [39m [38;5;252m; [39m
2020-08-05 10:37:11 +03:00
[38;5;252m [39m [38;5;246;03m// then use it to create a new, appropriately-prototyped object [39;00m
2019-02-17 16:03:46 +03:00
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;70;01mnew [39;00m [38;5;252m [39m [38;5;252mConstructor [39m [38;5;252m( [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;252m [39m [38;5;252m} [39m [38;5;252m; [39m
[38;5;252m} [39m
2020-08-06 08:28:08 +03:00
[38;5;246;03m// ES6 Additions [39;00m
[38;5;246;03m// The "let" keyword allows you to define variables in a lexical scope, [39;00m
[38;5;246;03m// as opposed to a block scope like the var keyword does. [39;00m
[38;5;70;01mlet [39;00m [38;5;252m [39m [38;5;252mname [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"Billy" [39m [38;5;252m; [39m
[38;5;246;03m// Variables defined with let can be reassigned new values. [39;00m
[38;5;252mname [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;214m"William" [39m [38;5;252m; [39m
[38;5;246;03m// The "const" keyword allows you to define a variable in a lexical scope [39;00m
[38;5;246;03m// like with let, but you cannot reassign the value once one has been assigned. [39;00m
[38;5;70;01mconst [39;00m [38;5;252m [39m [38;5;252mpi [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m3.14 [39m [38;5;252m; [39m
[38;5;252mpi [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;67m4.13 [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// You cannot do this. [39;00m
[38;5;246;03m// There is a new syntax for functions in ES6 known as "lambda syntax". [39;00m
[38;5;246;03m// This allows functions to be defined in a lexical scope like with variables [39;00m
[38;5;246;03m// defined by const and let. [39;00m
[38;5;70;01mconst [39;00m [38;5;252m [39m [38;5;252misEven [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m( [39m [38;5;252mnumber [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m=> [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;252mnumber [39m [38;5;252m [39m [38;5;252m% [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;67m0 [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;252misEven [39m [38;5;252m( [39m [38;5;67m7 [39m [38;5;252m) [39m [38;5;252m; [39m [38;5;252m [39m [38;5;246;03m// false [39;00m
[38;5;246;03m// The "equivalent" of this function in the traditional syntax would look like this: [39;00m
[38;5;70;01mfunction [39;00m [38;5;252m [39m [38;5;252misEven [39m [38;5;252m( [39m [38;5;252mnumber [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;252mnumber [39m [38;5;252m [39m [38;5;252m% [39m [38;5;252m [39m [38;5;67m2 [39m [38;5;252m [39m [38;5;252m=== [39m [38;5;252m [39m [38;5;67m0 [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m
[38;5;246;03m// I put the word "equivalent" in double quotes because a function defined [39;00m
[38;5;246;03m// using the lambda syntax cannnot be called before the definition. [39;00m
[38;5;246;03m// The following is an example of invalid usage: [39;00m
[38;5;252madd [39m [38;5;252m( [39m [38;5;67m1 [39m [38;5;252m, [39m [38;5;252m [39m [38;5;67m8 [39m [38;5;252m) [39m [38;5;252m; [39m
[38;5;70;01mconst [39;00m [38;5;252m [39m [38;5;252madd [39m [38;5;252m [39m [38;5;252m= [39m [38;5;252m [39m [38;5;252m( [39m [38;5;252mfirstNumber [39m [38;5;252m, [39m [38;5;252m [39m [38;5;252msecondNumber [39m [38;5;252m) [39m [38;5;252m [39m [38;5;252m=> [39m [38;5;252m [39m [38;5;252m{ [39m
[38;5;252m [39m [38;5;70;01mreturn [39;00m [38;5;252m [39m [38;5;252mfirstNumber [39m [38;5;252m [39m [38;5;252m+ [39m [38;5;252m [39m [38;5;252msecondNumber [39m [38;5;252m; [39m
[38;5;252m} [39m [38;5;252m; [39m