ECMAScript 2015
JS : Filling the gap
Standard
JS Specification
ECMA International — Organization
Standard 262 : ECMAScript — JS
Technical Committee 39 — Work group
Four stages process — Proposals
ES2015 Features
arrows
classes
enhanced object literals
template strings
destructuring
let + const
default + rest + spread
iterators + for..of
generators
unicode
modules
modules loaders
map & set
proxies
core APIs
symbols
subclassable built-ins
promises
reflect API
tail calls
binary and octal literals
let & const
// const & let are scoped at the block level
if(true) {
let foo = "bar"
}
foo // Error: Can't find variable: foo
// const prevents reassignation
const foo = "bar"
foo = "baz" // Error: "foo" is read-only
functions — arrows
var numbers = [1, 2, 3, 4, 5, 6];
// ES5 way
var even = numbers.filter(function(number) {
return number % 2 === 0;
});
// ES2015 way
var even = numbers.filter(number => number % 2 === 0);
functions — this
var numberObject = {
numbers: [],
getFromServer() {
// no more var self = this
$.ajax('http://api.com/numbers', data => {
this.numbers = data;
});
}
}
object literals
var name = "Bob";
var somebody = {
// New syntax replacing name: name,
name,
friends: [],
// New syntax replacing showFriends: function showFriends() {
showFriends() {
console.log(this.name + " knows " + this.friends);
},
// Computed property names
["prop_" + name]: "computed"
};
console.log(somebody.prop_Bob); // computed
functions — default
var numbers = [1, 2, 3, 4];
// ES5 way
var incrementArrayValues = function(array, increment) {
increment = increment || 1;
return array.map(function(value) {
return value + increment;
});
}
// ES2015 way
var incrementArrayValues = (array, increment = 1) => {
return array.map(value => value + increment);
}
console.log(incrementArrayValues(numbers)); // [2,3,4,5]
console.log(incrementArrayValues(numbers, 2)); // [3,4,5,6]
spread & rest
var fewNumbers = [2, 3, 4];
// Turn an array into consecutive arguments
var threeSum = (x, y, z) => x + y + z;
console.log(threeSum(...fewNumbers)); // 9
console.log([1, ...fewNumbers, 5, 6]); // [1, 2, 3, 4, 5, 6]
// Bind trailing parameters to an array
var incrementValues = (increment = 1, ...values) => {
return values.map(value => value + increment);
}
console.log(incrementValues(2, 5, 6, 7)); // [7, 8, 9]
destructuring
// binding using pattern matching
var [a, , b, c, d = 5] = [1,2,3];
console.log(a, c === undefined, d); // 1 true 5
var bob = {
name : "bob",
friends: [],
printFriends() { … }
};
var {name, friends: f} = bob;
console.log(name, f); // bob []
template strings
const multiline = `In ES5 this is
not legal.`
const unread = 1
console.log(`you have ${unread} message${unread !== 1 ? `s` : ``}`)
// you have 1 message
classes
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
// no coma here
toString() {
return `(${this.x}, ${this.y})`;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
console.log(new Point(1, 2).toString()); // (1, 2)
console.log(Point.distance({x: 1, y: 3}, {x: 6, y: 7})); // 6.4031242374328485
classes
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color;
}
toString() {
return super.toString() + ` in ${this.color}`;
}
}
var colored = new ColorPoint(1, 2, 'red');
console.log(colored.toString()); // (1, 2) in red
for ... of
// ES5 way
for (var property in object) {
if (object.hasOwnProperty(property)) {
console.log(object[property]);
}
}
for (var i=0; i<array.length; i++) {
console.log(array[i]);
}
// ES2015 way
for (let property of object) {
console.log(object[property]);
}
for (let value of array) {
console.log(value);
}
map & set
// Sets
var s = new Set();
s.add("foo").add("bar").add("foo");
console.log(s, s.has("foo")); // ["foo","bar"] true
// Maps
var m = new Map();
m.set("foo", 42);
m.set(s, "anything as a key");
console.log(m.get(s)); // anything as a key
weakmap & weakset
var refs = [{}]
// Weak Maps
var wm = new WeakMap();
wm.set(refs[0], "foo");
// Weak Sets
var ws = new WeakSet();
ws.add(refs[0]);
console.log(wm.has(refs[0]), ws.has(refs[0])); // true true
delete refs[0];
console.log(wm.has(refs[0]), ws.has(refs[0])); // false false
modules
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
console.log("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
import {sum, pi} from "lib/math";
console.log("2π = " + sum(pi, pi));
// no more global variables <3 <3 <3

WAIT A MINUTE.
What about browser support ?


You put ES2015 in
And get ES5 out
ECMAScript 2015
By Thibaut Dutartre
ECMAScript 2015
- 25