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