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. 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. ES6; // WTF?

  3. JavaScript Version History

  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. New Syntax

  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, 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
  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! (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?`;
  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)! 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 } }
  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()
  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, 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
  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 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
  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(); });
  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(){ // no variables inside a closure //

    leak into the global scope })(); { let variables // squiggly brackets control scope // let only exists within // var leaks outside }
  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
  27. Can I use it tho?

  28. Oh Yes*

  29. New Tools

  30. None
  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 (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']);
  34. Live Demo https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&code= http://rollupjs.org/