Slides prepared by Jean-Claude Dufourd and Cyril Concolato.
//
/* */
a
is different from A
a
=
3
console.log(a)
equivalent to
a = 3;
console.log(a);
undefined
var x;
var y = 0;
boolean
, number
, string
, object
, function
, or undefined
typeof
x = 0; typeof x; // integer -> "number"
x = -0.01; typeof x; // float -> "number"
x = "hello"; typeof x; // string -> "string"
x = 'Hello world!'; typeof x; // string -> "string"
x = true; typeof x; // boolean -> "boolean"
x = null; typeof x; // null object -> "object"
x = undefined; typeof x; // undefined value -> "undefined"
x = NaN; typeof x; // Not-a-Number -> "number"
var primes = [2,3,5,7];
primes[0]; // → 2
primes.length; // → 4
primes[primes.length – 1]; // → 7
primes["2"]; // → 5
primes.2; // → SyntaxError: unexpected number
var tableau = []; // initially empty
tableau[0] = "test"; // item 0 is added and its value set
tableau[1] = true; // each item may have a different type
tableau[2] = {};
tableau[3] = null;
tableau[4] = undefined;
tableau[5] = [];
tableau[18] = 2; // no items between 5 and 18
var book = {
topic: "JavaScript",
fat: true,
"major version": 1 // space in the name: to avoid !!!
};
book.topic; // → "JavaScript", pointed syntax
book ["fat"]; // → true, an object is an array of properties
book.author = "John Smith"; // add the 'author' property
book.contents = {}; // add the 'contents' property
book ["title"] = "JavaScript for Dummies"; // add the 'title' property
book ["main language"] = "french"; // property with a space
var empty = []; // empty array
empty.length; // → 0
var points = [ // array of objects
{x: 0, y: 1},
{x: 1, y: 1},
{x: 1, y: 1, z: 2}
];
var data = { // object containing objects
p1: {x: 0, y: 1},
p2: {x: 1, y: 1}
};
var trials = {
trial1: [[1, 2], [3, 4]], // array of array ~ matrix
trial2: [[1, 2], [4, 6]]
};
3 + 2; // → 5
3 * 2; // → 6
3 – 2; // → 1
3 / 2; // → 1.5
3 % 2; // → 1 // modulo
"3"+"2"; // → "32" // concatenation
"3"-"2"; // → 1 // type casting
var count = 0;
count++;
count--;
++count;
--count;
count += 2;
count -= 4;
count *= 5;
+"21"; // → 21 // converts "21" to a number 21
+"21toto"; // → NaN // impossible
parseInt("21"); // → 21 // converts "21" to a number 21
parseInt("21toto"); // → 21 // looks for an integer at the beginning
parseFloat("21.5toto"); // → 21.5 // looks for a float at the beginning
var x=3, y=2;
x == y // → false
x != y // → true
x < y // → false
x >= y // → true
"two" == "three" // → false
"two" > "three" // → true (lexicographic)
false == (x < y) // → true
(x == 2) && (y == 3) // → true
(x == 2) || (y == 4) // → true
!(x == y) // → true
|
|
==
(resp. !=
) tests equality (resp. difference) after conversion2 == 2 // → true
"2" == 2 // → true !!!attention
"2" != 2 // → false !!!attention
===
(resp. !==
) tests equality (resp. difference) with no conversion, on original types
"2" === 2 // → false
"2" !== 2 // → true
"22" > "3" // → false
+"22" > "3" // → true
"0" == false
> true
"" == false
> true
"" == "0"
> false ???
false
and thus the code does not executeif (false) { ... }
if (0) { ... }
if ("") { ... }
if (null) { ... }
if (undefined) { ... }
if (NaN) { ... })
true
, which may not be obvious to youif (true) { ... }
if (1) { ... }
if (-1) { ... }
if ("true") { ... }
if ("false") { ... }
if ("1") { ... }
if ("0") { ... }
if (Infinity) { ... }
if ([]) { ... }
if ({}) { ... }
if ([0]) { ... }
if ([1]) { ... }
while (...) {
...
}
do {
...
} while (...);
var i;
for (i=0; i<10; i++) {
...
}
for (var i=0; i<10; i++) {
...
}
// enumerate the properties of an object
for (var a in obj) {
...
}
// strict equality test
switch(type) {
case "a": // string
...
break;
case 1: // number
...
break;
default:
...
}
function inc(x) { return x+1; }
function mul(x, y) { return x*y; }
inc(4); // → 5
mul(2, inc(3)); // → 8
function (x) { return x-1; };
// anonymous function, useless
// because it cannot be called
(function() { ... })();
// anonymous function called upon definition
function f() { ... }
var points = {};
points.dist = f;
points.dist();
points.rotate = function(a) { ... };
points.rotate(30);
undefined
arguments
arrayfunction f(x,y) {
console.log("x: "+x+", y: "+y+", z: "+arguments[2]);
}
f(1,2,3); // x: 1, y: 2, z: 3
f(1,2); // x: 1, y: 2, z: undefined
f(1); // x: 1, y: undefined, z: undefined
var foo = function bar(){ return 12; };
typeof bar(); -> Reference Error
throw new Error('This is an Error!');
try {
…
} catch(e) {
…
} finally {
…
}
var o = { x: 1, y: 2};
delete o.x;
"x" in o; // → false, the property has disappeared
var a = [1,2,3];
delete a[2];
a.length; // → 3, unchanged array length
a[2]; // → undefined as new value
Let
)function test(o) {
var i = 0;
if (o !== null) {
var j = 0;
for(var k=0; k < 10; k++) {
console.log(k, i);
}
console.log(k); // variable k is still accessible
}
console.log(j); // variable j is still accessible
}
var currentScope = 0; // global scope
(function () {
var currentScope = 1, one = 'scope1';
(function () {
var currentScope = 2, two = 'scope2';
(function () {
var currentScope = 3, three = 'scope3';
alert(currentScope); // 3
alert(one + two + three); // scope1scope2scope3
})();
alert(currentScope); // 2
})();
alert(currentScope); // 1
})();
function run(obj) { ... }
run(a);
is equivalent to:
run = function (obj) { ... }
run(a);
function run(obj) {
function myPrint(x) {
console.log(x);
}
myPrint(obj.a);
myPrint(obj.b);
}
run({a: 1, b: "toto"}); // prints 1 then toto
myPrint(2); // ReferenceError: myPrint is not defined
boolean
: true
, false
number
: integers and floats (IEEE 754 watch the precision), +Infinity
, -Infinity
, NaN
0.1 + 0.2; // → 0.30000000000000004
string
null
undefined
1.toString(); // Uncaught SyntaxError: Unexpected token ILLEGAL(…)
true.toString(); → "true"
null.toString(); // Uncaught SyntaxError: Unexpected token ILLEGAL(…)
"toto".toString(); → "toto"
undefined.toString(); // Uncaught SyntaxError: Unexpected token ILLEGAL(…)
Object
and its derivatives
Boolean
, Number
, String
, Array
, Math
, Date
, Regexp
, Function
, Set
, JSON
…var b = new Boolean(true);
b.toString(); // → "true"
var n = new Number(3.14);
n.toString(); // → "3.14"
var s = "hello, world";
typeof s; // → "string" primitive type, not an object
s.x = 15; // → 15 no error because equivalent (new String (s)) x = 15
typeof s; // → "string" s did not change type
s.x // → undefined problem because the temporary String object has disappeared
s = new String ("hello, world");
typeof s; // → object: s is an object in its own right
s.x = 15; // → 15
s.x; // → 15 the property is persistent
var s = new String("hello, world");
s.charAt(0);
s.charAt(s.length-1);
s.substring(1,4);
s.slice(1,4);
s.slice(-3);
s.indexOf("l");
s.lastIndexOf("l");
s.indexOf("l", 3);
s.split(",");
s.replace("h", "H");
s.toUpperCase();
Math.pow(2,53);
Math.round(.6);
Math.ceil(.6);
Math.floor(.6);
Math.abs(-5);
Math.max(x,y,z);
Math.min(x,y,z);
Math.random();
Math.PI;
Math.E;
Math.sqrt(3);
Math.pow(3, 1/3);
Math.sin(0);
Math.log(10);
Math.log(100);
Math.LN10;
Math.log(512);
Math.LN2;
Math.exp(3);
a = new Array(); // usage not recommended
a = []; // recommended usage
a = [1, 2, 3];
a.length; // → 3
a.push(4);
b = a.pop(); // → 4
delete a[1]; // a[1] is now undefined
1 in a; // → false
a.length; // → 3 : length unmodified by delete
a.join(); // → "1,2,3"
a.join(" "); // → "1 2 3"
a.reverse();
a.sort();
a.concat(…);
a.slice(…); // -1 is the last element …
a.splice(…); // complex surgery
a.shift(); // = pop to the left
a.unshift(); // push push to the left
a.toString(); // like join()
a.forEach(f); // applies function f
a.map(f);
// applies function f + returns the array of results
a.filter(f); // selects according to predicate f
a.every(f); // && on f applied to items
a.some(f); // || on f applied to items
a.reduce(f,i);// applies f to items and sums
// results from left to right
a.reduceRight(f,i); // same from right to left
a.indexOf(i);
a.lastIndexOf(i);
Array.isArray(a);
this
is a keyword similar but different from other languages such as Java or C++this
defined:
this
represents the context overall execution, ie:
window
object in browsersthis === window; // true
global
object in NodeJSthis === global; // true
this
of the global execution context (if no object calling) in normal mode orundefined
in" strict mode ".var A = {};
function f() { return this === A; }
A.g = function () {
this.z = 2;
return this === A;
}
f(); // → false
A.g(); // → true
A.z; // → 2: property z is assigned on object A
this.z; // → undefined: z is unknown outside of A
function h() { this.x = 2; }
var B = new h();// any function can be a constructor
// in this case, in h: this === B → true
B.x; // → 2
this
var A = {
x: 2,
f: function (y, z) { console.log(this.x+y+z); }
};
A.f(1,2); // 5: f is called with this=A
var B = { x: 3 };
B.f(1,2); // TypeError: undefined is not a function
A.f.call(B, 1, 2); // 6: f is called with this=B
A.f.apply(B, [1, 2]); // 6: f is called with this=B
var g = A.f.bind(B, 1, 2); // creates a function
// this and other arguments are preset
g(); // f is called with this=B and the values 1 and 2
var A = { id: "toto"};
var id = "titi";
A.getId = function () {
alert(this.id);
setTimeout(function() {alert(this.id)}, 100);
}
A.getId(); // shows "toto" and 100ms later "titi"
this
in the inner function is not A but globalthat
, self
or me
.var A = { id: "toto"};
var id = "titi";
A.getId = function () {
var that = this;
alert(this.id);
setTimeout(function() {alert(that.id)}, 100);
}
A.getId();
// or you could
// setTimeout((function() {alert(this.id)}).bind(this), 100);
Now this is somewhere else
Now, this is somewhere else
for (a in b) { … }
include inherited properties (including system ones)hasOwnProperty()
for(a in b){
if (b.hasOwnProperty(a)) {
…
}
}
A stricter version of JavaScript can be used
"use strict";
function f() {
"use strict";
}
var
is not optionalthis
:this
is undefined
, instead of being the global objecteval ()
does not create anything in global (no variables, no functions)with
(which is so evil it is only mentioned here)eval("3+2"); // → 5
eval
is a function that runs where it is called, in the local contextnode.js
: runtime environment for JavaScript programs on the command line
npm
obj = JSON.parse(line);
line = JSON.stringify(obj);
JSON.stringify(book)
// → '{"topic":"JavaScript","fat":true,"author":"Jean Dupont","contents":{}}'
class
, extends
for prototype-based inheritance, see this=>
function (s){ return s.length }
is equivalent to
s => s.length
An arrow function does not have a this (or a context), it shares the this/context of the enclosing function.
$
and `
(backtick): string templatingvar name = "Bob", time = "today";
var t = `Hello ${name}, how are you ${time}?`;
console.log(t); // → "Hello Bob, how are you today?"
var t = [1,2,3];
var [a, , b] = t; // works for objects too
console.log(a,b); // → 1 3
var t2 = [...t, 4, 5, 6];
console.log(t2); // → [1, 2, 3, 4, 5, 6]
let
: variable with block scopeconst
: constantexport
, import
: gestion des modulesfunction f (x, y = 7, z = 42, ...a) {
return x + y + z
}
f(1) === 50
// with callback
fs.readFile("emails1A.txt",
function (content) { /* do something with content */ });
// with promise
fs.readFile("emails1A.txt")
.then(content => /* do something with content */)
.catch(error => /* display the error */);
Closures and OO moved elsewhere