ECMAScript 6

Drama in 5 acts

Piotr Lewandowski

@constjs

All temporary solutions become final

Act 1 - Preludium

ES 4

ES 6

ES 2015

Make JavaScript better

  • for complex application
  • for libraries
  • as target of code generators

Pave the Cowpaths

and don't break the web

Modules

Act 2

Design goals

  • Compact syntax
  • Support cyclic dependencies
  • Asynchronous loading
  • Configurable
// lib/math.js

export function sum(x, y) {
  return x + y;
}

export var pi = 3.141593;
// app.js

import * as math from "lib/math";

math.sum(22, 20); // 42


    // Default exports and named exports
    import myLib from 'src/mylib';
    import { function1, function2 } from 'src/mylib';

Importing

    // Renaming: import named1 as myNamed1
    import { function1 as fn, function2 } from 'src/mylib';
    // Importing the module as an object
    // (with one property per named export)
    import * as mylib from 'src/mylib';
    // Only load the module, don’t import anything
    import 'src/mylib';

Syntax

Act 3

Object {} enhancement

let firstName = 'Joe';
let lastName = 'Doe';

let person = {
    firstName,
    ['last' + 'Name']: lastName,
    getAge() {
        return 42;
    }
};

person.firstName // Joe
person.lastName // Doe
person.getAge() // 42
var firstName = 'Joe';
var lastName = 'Doe';

var person = {
    firstName: firstName,
    getAge: function() {
        return 42;
    }
};

person['last' + 'Name'] = lastName;

person.firstName // Joe
person.lastName // Doe
person.getAge() // 42

ES6

ES5

Destructuring

let [a, , b] = [1, 2, 3];
let person = { 
    firstName: 'Joe', 
    lastName: 'Doe'.
    age: 42
};

let { firstName, lastName } = person;

firstName // Joe
lastName // Doe
[a, b] = [b, a]

Spread operator

Math.max(...[1, 2, 3]);
// the same as
Math.max(1, 2, 3);
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);
[head, ...tail] = [1, 2, 3, 4, 5];

Scope - let & const

function foo() {
    a = 1;

    if (a) {
        var a;
        let b = a + 2;

        console.log( b );
    }

    console.log( a );
    console.log( b );
}
        console.log( b );   // 3
    }

    console.log( a );       // 1
    console.log( b );       // ReferenceError: `b` is not defined
}
function foo() {
    a = 1;                  // careful, `a` has been hoisted!

    if (a) {
        var a;              // hoisted to function scope!
        let b = a + 2;      // `b` block-scoped to `if` block!
    if (true) {
      const foo = "foo";

      // error
      foo = "bar";
    }

Functions

Act 4

Classes

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}
class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y);
        this.color = color;
    }
    toString() {
        return super.toString() + ' in ' + this.color;
    }
}
let cp = new ColorPoint(25, 8, 'green');
cp.toString(); // '(25, 8) in green'

console.log(cp instanceof ColorPoint); // true
console.log(cp instanceof Point); // true
console.log(typeof Point); // function

Arrow functions

            (x, y) => x + y

Lexical scope

class Person {
    constructor() {
        this.name = 'Joe';
    }

    // ...

    load() {
        xhrGet(data => {
            this.name = data.name;
        });
    }
}
function Person {
    this.name = 'Joe';

    // ...

    this.load = function() {
        var that = this;

        xhrGet(function(data) {
            that.name = data.name;
        });
    }
}

Lexical scope

vs

document.body.addEventListener('click', function(event) { 
    console.log(event, this) // EventObject, BodyElement
});
document.body.addEventListener('click', event => 
    console.log(event, this) // EventObject, WindowElement
);

Default parameters

function add(x = 0, y = 0) {
  return x + y;
}
function add(x, y) {
    x = x || 0;
    y = y || 0;

    return x + y;
}

ES6

ES5

Rest parameter

function friends(...friends) {
    friends.forEach(friend => {
        // ...
    }
}
function friends() {
    var friends = [].slice.call(arguments, 1);

    friends.forEach(function(friend) {
        // ...
    }
}

ES6

ES5

Can I use it?

Act 5 - Final

Compilators

  • TypeScript
  • Traceur

  • Babel

for back-end

  • Babel-node for node.js
  • io.js - fork of node.js

Stay tuned

and check

compatibility table

http://kangax.github.io/compat-table/es6/

Further reading

ECMAScript 6

By Piotr Lewandowski

ECMAScript 6

Intro to shiny new features from ECMAScript 6

  • 517