var foo = 2;
if (true) {
var bar = 1;
}will be compiled to
var foor = 2;
var bar = undefined;
if (true) {
bar = 1;
}Function declaration: function foo() { }
Function expression: var foo = function() { }; <- will be hoisted
Let does not do variable hoisting. Curly braces are the new scopes.
let i = 0;
let i = 2; // Will throw an 'already declarated error'let i = 0;
if (true) {
let i = 2;
} // Worksconst a = 0;
a = 1; // SyntaxError: Assignment to constant variablefunction test() {
// Do stuff
{
let i = 0; // This is a whole own scope
}
// Do stuff
}function a(first, last, ...other) {
// other = array
} Difference between arguments and ...other:
argumentsis sort of an array....otheris an actual array.argumentsreturns all the arguments. Including the first one....otheractually returns the rest.
- One per function
- Must be the last parameter
- Can't use
argumentsanymore - No possibility to define default values
var nums = [1,2,3];
log(nums); //logs [1,2,3];
log(...nums); // logs 1, 2, 3When to use:
function returnTwo(a,b) {
return [b,a];
}
var a = [1,2,3];
var b = returnTwo(a[0], a[1]); // Old way
var c = returnTwo(...a); // Better wayfunction getAddress() {
return {
city: 'Amsterdam',
state: 'NH',
zip: '1111AA'
}
}
let {city,state,zip} = getAddress();
log(city); // Amsterdam
log(state); // NH
log (zip); // 1111AARenaming variables:
let {city: c, state: s, zip: z} = getAddress();Object to variables as parameters
var person = {name: 'Marc', age: 23};
displayPerson(person);
function displayPerson({name, age}) {
log(name, age);
}Default values:
function displayPerson({name = 'No name provided', age = 0}) { }var x;
x = function() {return 2;}
x = () => 2; // return 2
x = () => { 2 }; // Executes 2, it doesn't return it
x = () => { return 2 }; // return 2
// Parentheses
x = () => {}; // No parameters, MUST HAVE PARENS
x = (val) => {}; // 1 parameter, OPTIONS PARENS
x = val => {}; // Works like the one above
x = (x, y) => {}; // Two or more parameters, MUST HAVE PARENSThis won't work:
var Widget = {
init: function() {
document.addEventListener('click', function() {
this.doSomething(); // This will break. This doesn't refer to the Widget scope.
});
},
doSomething: function() { }
};
Widget.init();This will work:
var Widget = {
init: function() {
document.addEventListener('click', () => {
this.doSomething();
});
},
doSomething: function() { }
};
Widget.init();Know when and when not to use the arrow function. Keep in mind that the this inside the function will change. It will take over the "parent scope".
function sayHello(name = 'World') {
log(`Hello ${name}!`);
}
sayHello('there') // Hello there!
sayHello(); // Hello World!
sayHello(undefined); // Hello World!class Foo {
}Constructor
class Foo {
constructor(name){
this.name = name;
}
}Private properties
const monsterHealth = Symbol();
class Monster {
constructor(name, health) {
this.name = name;
this[monsterHealth] = health;
}
}this[monsterHealth] will now be sort of private. The Symbol function generated a guid like character combination, so it would be almost impossible to predict the property name of the Monster class.
class Monster {
constructor(name) {
this.name = name;
}
get fullName() {
return `My name is ${this.name}`;
}
set fullName(name) {
this.name = name;
}
}
var monster = new Monster('Kevin');
log(monster.fullName); // My name is Kevin
monster.fullName = 'Harry';
log(monster.fullName); // My name is Harryclass Monster {
constructor(name) {
this.name = name;
}
}
class Godzilla extends Monster {
constructor() {
super('Godzilla');
}
}Export default:
// MyClass.js
class MyClass {
constructor() {}
}
export default MyClass;
// Main.js
import MyClass from 'MyClass';Export methods:
// lib.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
// Main.js
import { square, diag } from 'lib';
log(square(11));OR
// lib.js
import * as utils from 'lib';
log(utils.square(11));System.import('some_module')
.then(some_module => {
})var promise = new Promise(function(resolve, reject) {
if (true) {
resolve('it works');
} else {
reject('it works not');
}
});
return promise;Promise.all([promise1, promise2])
.then(function(results) {
log(results[0]);
log(results[1]);
});Chaining. Everything you return gets passed onto the next .then
get('users.all')
.then(function(usersString) {
return JSON.parse(usersString);
})
.then(function(users) {
myController.users = users;
});Promise.all(iterable); // Wait until all setle
Promise.race(iterable); // Wait until 1 settels
Promise.reject(reason); // Create a promise that has already been rejected.
Promise.resolve(reason); // Create a promise that has already been resolved.Normally a setTimeout(()=>{}, 1) will wait at least 1 millisecond, but gives no guarantee when it will execute.
Generator syntax:
function *three() { }function *three() {
yield 1;
yield 2;
return 3;
}For example, we use var geni = three();, but it won't execute the code. It returns the generator iterator.
In order to execute it, you call geni.next();. The fierst time you call next() it returns the first yield. Yield is kind of like return, but it's more like pause and send this value back.
The first time geni.next() returns { value: 1, done: false }.
geni.next(); // { value: 2, done: false }
geni.next(); // { value: 3, done: true }