Skip to content

Instantly share code, notes, and snippets.

@marcveens
Created April 21, 2017 07:35
Show Gist options
  • Select an option

  • Save marcveens/0ac0ea684c89f499a0a0ccb77937d595 to your computer and use it in GitHub Desktop.

Select an option

Save marcveens/0ac0ea684c89f499a0a0ccb77937d595 to your computer and use it in GitHub Desktop.
ES6 intro

Variable hoisting

var foo = 2;
if (true) {
    var bar = 1;
}

will be compiled to

var foor = 2;
var bar = undefined; 
if (true) {
    bar = 1;
}

Function Hoisting

Function declaration: function foo() { }

Function expression: var foo = function() { }; <- will be hoisted

LET

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;
    } // Works

CONST

const a = 0;  
a = 1; // SyntaxError: Assignment to constant variable

Block functions

function test() {
    // Do stuff
    {
        let i = 0; // This is a whole own scope
    }
    // Do stuff
}

Rest parameters

function a(first, last, ...other) {
    // other = array
} 

Difference between arguments and ...other:

  1. arguments is sort of an array. ...other is an actual array.
  2. arguments returns all the arguments. Including the first one. ...other actually returns the rest.

Rest parameters rules

  • One per function
  • Must be the last parameter
  • Can't use arguments anymore
  • No possibility to define default values

Spread operator

var nums = [1,2,3];

log(nums); //logs [1,2,3];
log(...nums); // logs 1, 2, 3

When 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 way

Destructing

function getAddress() {
    return {
        city: 'Amsterdam',
        state: 'NH',
        zip: '1111AA'
    }
}

let {city,state,zip} = getAddress();

log(city); // Amsterdam
log(state); // NH
log (zip); // 1111AA

Renaming 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}) { }

Arrow functions

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 PARENS

This

This 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".

Default parameters

function sayHello(name = 'World') {
    log(`Hello ${name}!`);
}

sayHello('there') // Hello there!
sayHello(); // Hello World!
sayHello(undefined); // Hello World!

Classes

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.

Getters and setters

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 Harry

Extending classes

class Monster {
    constructor(name) {
        this.name = name;
    }
}

class Godzilla extends Monster {
    constructor() {
        super('Godzilla');
    }
}

Modules

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));

Async loading API

System.import('some_module')
.then(some_module => {

})

Promises

var promise = new Promise(function(resolve, reject) {
    if (true) {
        resolve('it works');
    } else {
        reject('it works not');
    }
});

return promise;

Promise instance

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.

Generators

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 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment