ES6/ES2015
ECMAScript 6, also known as ECMAScript 2015, is the latest version of
the ECMAScript standard. ES6 is a significant update to the language,
and the first update to the language since ES5 was standardized in
2009. Implementation of these features in major JavaScript engines is
underway now.
“
”Luke Hoban - ES6 Features
ES6; // WTF?
JavaScript Version History
● ES3 / JavaScript 1.5
○ Poor error reporting
○ Slightly quirky and inconsistent
● ES5 / JavaScript 1.8
○ “use strict” opt-in
● ES6 / JavaScript 2015
○ New syntax
○ New features
Versions, browsers & support
● ES3 / JavaScript 1.5
○ Poor error reporting
○ Slightly quirky and inconsistent
● ES5 / JavaScript 1.8
○ “use strict” opt-in
● ES6 / JavaScript 2015
○ New syntax
○ New features
Versions, browsers & support
All Modern Browsers
Future tech /
partial support
New Syntax
The New Syntax
● Constants
● Block scoping
● Better parameters
● String templates
● Arrow functions
● New shorthand notation
● Classes
● Modules
● Promises
● + more
¯_(ツ)_/¯
¯_(ツ)_/¯
● Less boilerplate, more actual code
● More fine-grained control, more predictable behaviours
● Standardisation / formal adoption of popular concepts
Less Boilerplate, More Code.
● Parameter enhancements replace frequently written custom code
● String templates improve readability
● New shorthand codes
● Standard ‘class’ support to replace common boilerplates
● Standard ‘module’ support to replace anti-patterns & libraries
Default Parameters!
function formatText(text, style,
specialchars, options) {
if (style == undefined) {
style = 'uncompressed';
}
if (specialchars == undefined) {
specialchars = '&';
}
var optionsToUse = options || { useTabs:
true, indent: 4 };
// etc
function formatText(text,
style = 'uncompressed',
specialchars = '&',
options = { useTabs: true, indent: 4 }) {
// etc
Template Literals! (New Strings!)
var customer = { name: "Foo" };
var card = { amount: 7, product: "Bar",
unitprice: 42 };
var message = "Hello " + customer.name +
",n" + "want to buy " + card.amount + " ""
+ card.product + "" forn" + "a total of " +
(card.amount * card.unitprice) + " bucks?";
var customer = { name: "Foo" }
var card = { amount: 7, product: "Bar",
unitprice: 42 }
var message = `Hello ${customer.name},
want to buy ${card.amount} "${card.product}"
for
a total of ${card.amount * card.unitprice}
bucks?`;
Nu Shrthnd!
var obj = { x: x, y: y };
var tmp = getASTNode();
var op = tmp.op;
var lhs = tmp.lhs;
var rhs = tmp.rhs;
var nums = evens.map(function (v, i) {
return v + i;
});
var obj = { x, y };
var { op, lhs, rhs } = getASTNode()
var nums = evens.map((v, i) => v + i)
Classes!
var Shape = function (id, x, y) {
this.id = id;
this.move(x, y);
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
class Shape {
constructor (id, x, y) {
this.id = id
this.move(x, y)
}
move (x, y) {
this.x = x
this.y = y
}
}
Classes (with inheritance)!
var Rectangle = function (id, x, y, width,
height) {
Shape.call(this, id, x, y);
this.width = width;
this.height = height;
};
Rectangle.prototype =
Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var Circle = function (id, x, y, radius) {
Shape.call(this, id, x, y);
this.radius = radius;
};
Circle.prototype =
Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y)
this.width = width
this.height = height
}
}
class Circle extends Shape {
constructor (id, x, y, radius) {
super(id, x, y)
this.radius = radius
}
}
Classes (with static methods)!
var Rectangle = function (id, x, y, width,
height) {
…
};
Rectangle.defaultRectangle = function () {
return new Rectangle("default", 0, 0,
100, 100);
};
var Circle = function (id, x, y, width,
height) {
…
};
Circle.defaultCircle = function () {
return new Circle("default", 0, 0, 100);
};
var defRectangle =
Rectangle.defaultRectangle();
var defCircle = Circle.defaultCircle();
class Rectangle extends Shape {
…
static defaultRectangle () {
return new Rectangle("default", 0, 0,
100, 100)
}
}
class Circle extends Shape {
…
static defaultCircle () {
return new Circle("default", 0, 0,
100)
}
}
var defRectangle =
Rectangle.defaultRectangle()
var defCircle = Circle.defaultCircle()
Modules!
// lib/math.js
LibMath = {};
LibMath.sum = function (x, y) { return x + y
};
LibMath.pi = 3.141593;
// someApp.js
var math = LibMath;
console.log("2π = " + math.sum(math.pi,
math.pi));
// otherApp.js
var sum = LibMath.sum, pi = LibMath.pi;
console.log("2π = " + sum(pi, pi));
// lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593
// someApp.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))
Modules (without RequireJS)!
// math.js
define([],function(){
return {
cube: function cube ( x ) {
return x * x * x;
}
}
})
// main.js
require(["math"], function(math) {
console.log( math.cube( 5 ) ); // 125
})
// math.js
export function cube ( x ) {
return x * x * x;
}
// main.js
import { cube } from './maths.js';
console.log( cube( 5 ) ); // 125
More Control, More Predictable
● Block scoping reduces variable leaks, ‘side effects’ and memory usage
● const, let and var improve readability and reduce cognitive load
● Arrow functions control this, replacing common anti-patterns
● Promises make asynchronous operations easier to write without callback
hell and/or the need for an external library
Block scoping
const myConst = 42;
var myVar = 42;
{
let myLet = 42;
console.log(myVar, myLet); // 42, 42
}
console.log(myVar, myLet); // 42, undefined
myConst = 43; // Error!
function(){
let myLet = 2;
}
console.log(myLet); // undefined
console.log(myVar); // 42
Arrow Functions
console.log(this);
// window.document
function tryThis() {
console.log(this);
}
tryThis();
// window.document
$('.button').on('click', tryThis);
// MouseClick.Event
$.ajax()...success(tryThis);
// XMLHTTPRequest
element.apply(tryThis);
// element
console.log(this);
// window.document
var tryThis = () => {
console.log(this);
}
tryThis();
// window.document
$('.button').on('click', tryThis);
// window.document
$.ajax()...success(tryThis);
// window.document
element.apply(tryThis);
// window.document
Arrow Functions
// pass stuff without creating a new scope!
(inputValue, options) => functionToExecute(inputValue, 'customValue', options);
// rather than the old way:
function(inputValue, options) {
functionToExecute(inputValue, 'customValue', options);
}
// no more
var thiz = this;
$('.button').on('click', function() {
thiz.doStuff();
});
// this instead
$('.button').on('click', () => {
this.doStuff();
});
Promises, Promises
function msgAfterTimeout (msg, who, timeout, onDone) {
setTimeout(function () {
onDone(msg + " Hello " + who + "!");
}, timeout);
}
msgAfterTimeout("", "Foo", 100, function (msg) {
msgAfterTimeout(msg, "Bar", 200, function (msg) {
console.log("done after 300ms:" + msg);
});
});
function msgAfterTimeout (msg, who, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout)
})
}
msgAfterTimeout("", "Foo", 100).then((msg) =>
msgAfterTimeout(msg, "Bar", 200)
).then((msg) => {
console.log(`done after 300ms:${msg}`)
})
By Popular Demand
● Block scoping removes the necessity of closures
● Constants remove the need for libraries like immutable.js
● Class support standardises the ‘prototype’ and ‘object’ patterns
● Modules support standardises CommonJS / AMD patterns
● Promises standardise async behaviour and remove the need for custom
polyfill libraries
Block scoping!
(function(){
// no variables inside a closure
// leak into the global scope
})();
{
let variables
// squiggly brackets control scope
// let only exists within
// var leaks outside
}
Recap: The exciting bits.
● Block scoping reduces variable leaks, ‘side effects’ and memory usage
● const, let and var improve readability and reduce cognitive load
● Parameter enhancements replace frequently written custom code
● String templates improve readability
● Arrow functions control this, replacing common anti-patterns
● New shorthand code reduces repetition repetition
● Proper class support replaces common boilerplates and antipatterns
● Modules enable better code organisation without file concatenation steps
or external module-loader libraries
● Promises make asynchronous operations easier without the need for an
external library
Can I use it tho?
Oh Yes*
New Tools
Enter the Transpiler
1. Write source code in ES6
2. Compile source code to ES5
3. ???
4. Profit
Transpiling ES6
require("load-grunt-tasks")(grunt); // npm install --save-dev load-grunt-tasks
grunt.initConfig({
"babel": {
options: {
sourceMap: true
},
dist: {
files: {
"dist/app.js": "src/app.js"
}
}
}
});
grunt.registerTask("default", ["babel"]);
Transpiling ES6 (with Rollup)
grunt.loadNpmTasks('grunt-rollup'); // npm install grunt-rollup --save-dev
grunt.initConfig({
rollup: {
dist: {
options: {
plugins: [
babel()
]
sourceMap: true
},
files: {
'js/index.js': 'js_source/index.js'
}
}
},
});
grunt.registerTask('default', ['rollup']);
Live Demo
https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&code=
http://rollupjs.org/

ES6, WTF?

  • 1.
    ES6/ES2015 ECMAScript 6, alsoknown as ECMAScript 2015, is the latest version of the ECMAScript standard. ES6 is a significant update to the language, and the first update to the language since ES5 was standardized in 2009. Implementation of these features in major JavaScript engines is underway now. “ ”Luke Hoban - ES6 Features
  • 2.
  • 3.
  • 4.
    ● ES3 /JavaScript 1.5 ○ Poor error reporting ○ Slightly quirky and inconsistent ● ES5 / JavaScript 1.8 ○ “use strict” opt-in ● ES6 / JavaScript 2015 ○ New syntax ○ New features Versions, browsers & support
  • 5.
    ● ES3 /JavaScript 1.5 ○ Poor error reporting ○ Slightly quirky and inconsistent ● ES5 / JavaScript 1.8 ○ “use strict” opt-in ● ES6 / JavaScript 2015 ○ New syntax ○ New features Versions, browsers & support All Modern Browsers Future tech / partial support
  • 6.
  • 7.
    The New Syntax ●Constants ● Block scoping ● Better parameters ● String templates ● Arrow functions ● New shorthand notation ● Classes ● Modules ● Promises ● + more
  • 8.
  • 9.
    ¯_(ツ)_/¯ ● Less boilerplate,more actual code ● More fine-grained control, more predictable behaviours ● Standardisation / formal adoption of popular concepts
  • 10.
    Less Boilerplate, MoreCode. ● Parameter enhancements replace frequently written custom code ● String templates improve readability ● New shorthand codes ● Standard ‘class’ support to replace common boilerplates ● Standard ‘module’ support to replace anti-patterns & libraries
  • 11.
    Default Parameters! function formatText(text,style, specialchars, options) { if (style == undefined) { style = 'uncompressed'; } if (specialchars == undefined) { specialchars = '&'; } var optionsToUse = options || { useTabs: true, indent: 4 }; // etc function formatText(text, style = 'uncompressed', specialchars = '&', options = { useTabs: true, indent: 4 }) { // etc
  • 12.
    Template Literals! (NewStrings!) var customer = { name: "Foo" }; var card = { amount: 7, product: "Bar", unitprice: 42 }; var message = "Hello " + customer.name + ",n" + "want to buy " + card.amount + " "" + card.product + "" forn" + "a total of " + (card.amount * card.unitprice) + " bucks?"; var customer = { name: "Foo" } var card = { amount: 7, product: "Bar", unitprice: 42 } var message = `Hello ${customer.name}, want to buy ${card.amount} "${card.product}" for a total of ${card.amount * card.unitprice} bucks?`;
  • 13.
    Nu Shrthnd! var obj= { x: x, y: y }; var tmp = getASTNode(); var op = tmp.op; var lhs = tmp.lhs; var rhs = tmp.rhs; var nums = evens.map(function (v, i) { return v + i; }); var obj = { x, y }; var { op, lhs, rhs } = getASTNode() var nums = evens.map((v, i) => v + i)
  • 14.
    Classes! var Shape =function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; }; class Shape { constructor (id, x, y) { this.id = id this.move(x, y) } move (x, y) { this.x = x this.y = y } }
  • 15.
    Classes (with inheritance)! varRectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); this.width = width; this.height = height; }; Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var Circle = function (id, x, y, radius) { Shape.call(this, id, x, y); this.radius = radius; }; Circle.prototype = Object.create(Shape.prototype); Circle.prototype.constructor = Circle; class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y) this.width = width this.height = height } } class Circle extends Shape { constructor (id, x, y, radius) { super(id, x, y) this.radius = radius } }
  • 16.
    Classes (with staticmethods)! var Rectangle = function (id, x, y, width, height) { … }; Rectangle.defaultRectangle = function () { return new Rectangle("default", 0, 0, 100, 100); }; var Circle = function (id, x, y, width, height) { … }; Circle.defaultCircle = function () { return new Circle("default", 0, 0, 100); }; var defRectangle = Rectangle.defaultRectangle(); var defCircle = Circle.defaultCircle(); class Rectangle extends Shape { … static defaultRectangle () { return new Rectangle("default", 0, 0, 100, 100) } } class Circle extends Shape { … static defaultCircle () { return new Circle("default", 0, 0, 100) } } var defRectangle = Rectangle.defaultRectangle() var defCircle = Circle.defaultCircle()
  • 17.
    Modules! // lib/math.js LibMath ={}; LibMath.sum = function (x, y) { return x + y }; LibMath.pi = 3.141593; // someApp.js var math = LibMath; console.log("2π = " + math.sum(math.pi, math.pi)); // otherApp.js var sum = LibMath.sum, pi = LibMath.pi; console.log("2π = " + sum(pi, pi)); // lib/math.js export function sum (x, y) { return x + y } export var pi = 3.141593 // someApp.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))
  • 18.
    Modules (without RequireJS)! //math.js define([],function(){ return { cube: function cube ( x ) { return x * x * x; } } }) // main.js require(["math"], function(math) { console.log( math.cube( 5 ) ); // 125 }) // math.js export function cube ( x ) { return x * x * x; } // main.js import { cube } from './maths.js'; console.log( cube( 5 ) ); // 125
  • 19.
    More Control, MorePredictable ● Block scoping reduces variable leaks, ‘side effects’ and memory usage ● const, let and var improve readability and reduce cognitive load ● Arrow functions control this, replacing common anti-patterns ● Promises make asynchronous operations easier to write without callback hell and/or the need for an external library
  • 20.
    Block scoping const myConst= 42; var myVar = 42; { let myLet = 42; console.log(myVar, myLet); // 42, 42 } console.log(myVar, myLet); // 42, undefined myConst = 43; // Error! function(){ let myLet = 2; } console.log(myLet); // undefined console.log(myVar); // 42
  • 21.
    Arrow Functions console.log(this); // window.document functiontryThis() { console.log(this); } tryThis(); // window.document $('.button').on('click', tryThis); // MouseClick.Event $.ajax()...success(tryThis); // XMLHTTPRequest element.apply(tryThis); // element console.log(this); // window.document var tryThis = () => { console.log(this); } tryThis(); // window.document $('.button').on('click', tryThis); // window.document $.ajax()...success(tryThis); // window.document element.apply(tryThis); // window.document
  • 22.
    Arrow Functions // passstuff without creating a new scope! (inputValue, options) => functionToExecute(inputValue, 'customValue', options); // rather than the old way: function(inputValue, options) { functionToExecute(inputValue, 'customValue', options); } // no more var thiz = this; $('.button').on('click', function() { thiz.doStuff(); }); // this instead $('.button').on('click', () => { this.doStuff(); });
  • 23.
    Promises, Promises function msgAfterTimeout(msg, who, timeout, onDone) { setTimeout(function () { onDone(msg + " Hello " + who + "!"); }, timeout); } msgAfterTimeout("", "Foo", 100, function (msg) { msgAfterTimeout(msg, "Bar", 200, function (msg) { console.log("done after 300ms:" + msg); }); }); function msgAfterTimeout (msg, who, timeout) { return new Promise((resolve, reject) => { setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout) }) } msgAfterTimeout("", "Foo", 100).then((msg) => msgAfterTimeout(msg, "Bar", 200) ).then((msg) => { console.log(`done after 300ms:${msg}`) })
  • 24.
    By Popular Demand ●Block scoping removes the necessity of closures ● Constants remove the need for libraries like immutable.js ● Class support standardises the ‘prototype’ and ‘object’ patterns ● Modules support standardises CommonJS / AMD patterns ● Promises standardise async behaviour and remove the need for custom polyfill libraries
  • 25.
    Block scoping! (function(){ // novariables inside a closure // leak into the global scope })(); { let variables // squiggly brackets control scope // let only exists within // var leaks outside }
  • 26.
    Recap: The excitingbits. ● Block scoping reduces variable leaks, ‘side effects’ and memory usage ● const, let and var improve readability and reduce cognitive load ● Parameter enhancements replace frequently written custom code ● String templates improve readability ● Arrow functions control this, replacing common anti-patterns ● New shorthand code reduces repetition repetition ● Proper class support replaces common boilerplates and antipatterns ● Modules enable better code organisation without file concatenation steps or external module-loader libraries ● Promises make asynchronous operations easier without the need for an external library
  • 27.
    Can I useit tho?
  • 28.
  • 29.
  • 31.
    Enter the Transpiler 1.Write source code in ES6 2. Compile source code to ES5 3. ??? 4. Profit
  • 32.
    Transpiling ES6 require("load-grunt-tasks")(grunt); //npm install --save-dev load-grunt-tasks grunt.initConfig({ "babel": { options: { sourceMap: true }, dist: { files: { "dist/app.js": "src/app.js" } } } }); grunt.registerTask("default", ["babel"]);
  • 33.
    Transpiling ES6 (withRollup) grunt.loadNpmTasks('grunt-rollup'); // npm install grunt-rollup --save-dev grunt.initConfig({ rollup: { dist: { options: { plugins: [ babel() ] sourceMap: true }, files: { 'js/index.js': 'js_source/index.js' } } }, }); grunt.registerTask('default', ['rollup']);
  • 34.