ES6; // WTF?

50bd52fe63e2264aeae49b33d0e9102e?s=47 James Ford
September 01, 2016

ES6; // WTF?

What is ES6/ES2015, and what does it mean for Javascript development? What does the new syntax look like, and how can we use it today? Featuring side-by-side comparisons!

50bd52fe63e2264aeae49b33d0e9102e?s=128

James Ford

September 01, 2016
Tweet

Transcript

  1. 1.

    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
  2. 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
  3. 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
  4. 7.

    The New Syntax • Constants • Block scoping • Better

    parameters • String templates • Arrow functions • New shorthand notation • Classes • Modules • Promises • + more
  5. 9.

    ¯\_(ツ)_/¯ • Less boilerplate, more actual code • More fine-grained

    control, more predictable behaviours • Standardisation / formal adoption of popular concepts
  6. 10.

    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
  7. 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
  8. 12.

    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 + "\" for\n" + "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?`;
  9. 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)
  10. 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 } }
  11. 15.

    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 } }
  12. 16.

    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()
  13. 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))
  14. 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
  15. 19.

    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
  16. 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
  17. 21.

    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
  18. 22.

    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(); });
  19. 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}`) })
  20. 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
  21. 25.

    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 }
  22. 26.

    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
  23. 28.
  24. 29.
  25. 30.
  26. 31.

    Enter the Transpiler 1. Write source code in ES6 2.

    Compile source code to ES5 3. ??? 4. Profit
  27. 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"]);
  28. 33.

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