es6-presentation-1



es6-presentation-1

0 0


es6-presentation-1


On Github tdoherty / es6-presentation-1

ECMAScript 6 In Depth

Welcome to the first in a planned 3 part series on ES Who am I? What does Agilysys do? How many are already familiar with ES6?

ECMAWhat?

ECMAScript is the standardized language

Best known implementation is JavaScript

ECMAScript 6 is a superset of current version

other implementations include JScript, ActionScript

What's the big deal?

ES5 was a pretty small release Compromise from aborted ES4 Don't we already have these features in lots of other languages?

JavaScript

This is how many devs from other languages see JS Perhaps fairly to some extent

Despite its quirks...

JavaScript is the most widely deployed programming language in the world

Browser : Server : Database : Automation

It's king of the web, no other language even comes close

Any application that can be written in JavaScript, will eventually be written in JavaScript.

~Atwood's Law

Background

Current version is ECMAScript 5.1 (2011)

Next version is officially ECMAScript 2015

ECMAScript 6 (ES6) mindshare tough to penetrate

ES 5.1 is a maintenance release atop 5.0 (2009) Year in name intended to reflect faster release cadence

Background

ECMAScript 6 is complete

Spec is finalized

Publication in June 2015

Browsers continually implementing features

Fully compliant browser by end of 2015?

Using ES6 Today

Transpile: ES6 -> ES5

ES6 Shims

Sourcemaps

Module System

Transpilers: Babel, Traceur, TypeScript Shims: es6-shim Sourcemaps: transpiler options Module system: Browserify, webpack, JSPM

Part I

  • Block Scoping
  • Arrow Functions
  • Object Literal Syntax
  • Classes
  • Default Parameters
  • "..." Operator
  • Destructring Assigment
  • Template Strings / Tagged Templates
  • Modules

Block Scoping

ES < 6 has lexical scoping only

ES6 introduces let and const for block scoping

Block scoped function declarations

ES <= 5.1 has lexical scoping only.
    let foo = 'bar';
    console.log(foo); // bar
    
Let is not hoisted
    console.log(foo); // Reference Error
    let foo = 'bar';
    
Let is not hoisted, so declaration must come before usage
    var foo = 'bar';
    {
      let foo = 'baz';
      console.log(foo); // baz
    }
    console.log(foo); // bar
    
True block scoping here
    const foo = 'bar';
    console.log(foo) // bar
    foo = 'baz' // TypeError
    
Emulates immutability by disallowing reassignment

const locks assignment only, not value

    const foo = [1, 2, 3];
    foo = [4, 5];          // TypeError
    foo.concat([4, 5]);
    console.log(foo);      // [1, 2, 3, 4, 5]
    
Const is not immutable, the value of the entity can be changed Only prevents reassignment, values are mutable
    {
      foo();             // ok

      function foo() {}
    }

    foo();               // ReferenceError
    
Block scoped functions

Arrow Functions

Terse function syntax

Lexical "this" binding

Inspired by C# and CoffeeScript

Arrow function intro
    // ES5
    function square(x) {
      return x * x;
    }

    // ES6
    let square = x => x * x;
    
    // ES5
    [1, 2, 3].map(function (x) {
      return x * x;
    }

    // ES6
    [1, 2, 3].map(x => x * x);
    
    arg => expr

    arg => { stmt1; stmt2; ... }

    (arg1, arg2, ...) => expr

    (arg1, arg2, ...) => { stmt1; stmt2; ... }
    
    // ES5
    function Widget() {
      var that = this;
      var b = document.querySelector('#btn1');
      b.addEventListener('click', function() {
        that.someMethod();
      });
    }

    // ES6
    function Widget() {
      let b = document.querySelector('#btn1');
      b.addEventListener('click', () => {
        this.someMethod();
      });
    }
    
      
      
      
        
        
          
        
      
      
      
        
          
        
      
    
    
.forEach() takes an optional 2nd 'this' param, example is to make a point only

() => {} can be used almost everywhere function() is used, but...

Best for short, simple functions, where terseness shines

Always function expressions, can't be hoisted

Deprecated "arguments" object is not available

Not a drop-in replacement for function.

Object Literal Syntax

ES6 introduces object literal enhancements

Property shorthand

Compact method syntax

Computed properties

    var a = 1, b = 2;

    // ES5
    var foo = { a: a, b: b };

    // ES6
    let foo = { a, b };
    
    // ES5
    var foo = {
      bar: function (x) {
        return x;
      }
    }

    // ES6
    let foo = {
      bar(x) {
        return x;
      }
    }
    
    let foo = {
      ['foo' + 'Bar']: function (x) {
        return x + x;
      }
    }

    foo.fooBar(3); // 6
    
Main value is Symbols No name clashes Private methods/properties

Classes

Classes are the most divisive ES6 addition

Syntactic sugaring of constructor functions and prototypes

    // ES5
    function Foo(bar) {
      this.bar = bar;
    }

    Foo.prototype.baz = function() {
    }

    var foo = new Foo('bar');
   
    // ES6
    class Foo {
      constructor(bar) {
        this.bar = bar;
      }
      baz() {
      }
    }

    let foo = new Foo('bar');
    
    class Foo {
      constructor(bar) {
        this.bar = bar;
      }
      static baz() {
      }
    }

    let foo = new Foo('bar');
    Foo.baz()  // ok
    foo.baz(); // undefined
    
    class Foo {
      constructor(bar) {
        this.bar = bar;
      }
    }

    class FooBar extends Foo {
      constructor(bar) {
        super(bar);
      }
    }

    let fooBar = new FooBar('baz');
    console.log(fooBar.bar); // baz
    fooBar instanceof Foo // true
    
Mention getters / setters, avaiable on objects in ES5
    class Foo extends Array{
      first() { return this[0]; }
      last() { return this[this.length - 1]; }
    }

    let foo = new Foo(1, 2, 3);
    foo.first(); // 1
    foo.last(); // 3
    foo instanceof Array // true
    

Classes - Pros

Friendlier to class-based OO developers

Standardized vs. various lib/framework implementations

Tooling (IDEs, transpilers, type checkers, etc.)

Subclassing built-in objects

Classes - Cons

Syntax very different from semantics

Constructor-based inheritance

Encourages inheritance over composition

super()

You can set up prototype chains without constructors Constructors tie object creation with initialization

Default Parameters

    // ES5
    function foo (bar) {
      var bar = bar || 'baz';
    }

    // ES6
    function foo(bar='baz') {
    }
    
    function f({foo='fee', bar='baz'}={}) {
      console.log(foo + ', ' + bar);
    }

    f({foo: 'fum', bar: 'bim'}); // fum, bim
    f({foo: 'fum'}); // fum, baz
    f(); // fee, baz
    
    function f(arg, cb=Function.prototype) {
      // do something...
      cb(arg);
    }

    let myCb = x => { console.log(x); };

    f('foo', myCb); // foo
    f('foo');       // no-op
    

The "..." or "spread" operator

Dual personality:

Gathering values ("rest" parameters)

Spreading values ("spread" operator)

"Rest" Parameters

    // ES5
    function foo () {
      var args = [].slice.call(arguments);
      console.log(args.shift()); ok
    }

    // ES6
    function foo(...rest) {
      console.log(rest.shift()); ok
    }
    
    function f(arg, ...rest) {} // ok

    function f(arg1, arg2, ...rest) {} // ok

    function f(...rest, arg) {} // SyntaxError

    

Spread Operator

    let arr1 = [4, 5];
    let arr2 = [1, 2, 3, ...arr1, 6];
    console.log(arr2); // [1, 2, 3, 4, 5, 6]
    
    function foo (a, b, c, d, e, f) {}

    let args = [3, 4];
    foo(1, 2, ...args, 5, 6);
    
    // 'apply' for constructors
    let dateParts = [1995, 11, 1];

    new Date(...dateParts); // Fri Dec 01 1995
    

Destructuring Assignment

Concise syntax for extracting data from arrays and objects

    // ES5
    var arr = [1, 2, 3];
    var a = arr[0];
    var b = arr[1];
    var c = arr[2];

    // ES6
    let [a, b, c] = [1, 2, 3];
    
    let [a, , , [, e]] = [1, 2, 3, [4, 5]];

    console.log(a); // 1
    console.log(e); // 5
    
    let a = 1, b = 2;

    [b, a] = [a, b];

    console.log(a); // 2
    console.log(b); // 1
    
    let [a, b, ...rest] = [1, 2, 3, 4, 5];

    console.log(rest.length);  // 3
    console.log(rest.shift()); // 3
    console.log(rest.shift()); // 4
    console.log(rest.shift()); // 5
    
    // ES5
    var obj = {a: 1, b: 2};
    var a = obj.a;
    var b = obj.b;

    // ES6
    let {a, b} = {a: 1, b: 2};
    
    let {b: {c, d}} = {a: 1, b: {c: 3, d: 4}};

    console.log(c); // 3
    console.log(d); // 4
    
    let {a: one, b: two} = {a: 1, b: 2};

    console.log(one); // 1
    console.log(one); // 2
    
Note source: target syntax

Template Strings

String literals allowing embedded expressions

Supports multi-line strings

Add an example of expression interpolation?
    // ES5
    var name = 'Dave';
    var greeting = 'Good morning ' + name;

    // ES6
    let name = 'Dave';
    let greeting = `Good morning ${name}`;
    
    // ES5
    var aString = 'string text line\n' +
      'string text line2\n';

    // ES6
    let aString = `string text line 1
      string text line2`;
    
Add an example of expression interpolation?

Tagged Template Strings

Modify output of template strings with a function

Function takes an array of string literals, and ...rest values

    function upper(strs, ...vals) {
      return strs.reduce(function (p, c, i) {
        if (i > 0) {
          p += vals[i-1].toUpperCase();
        }
        return p + c;
      }, '');
    }

    let him = 'Dave', me = 'Hal';
    let str = upper`Hello ${him}, it's ${me}`;
    console.log(str); // Hello DAVE, it's HAL
    
String.raw
    function raw(strs, ...vals) {
      console.log(strs);
      console.log(strs.raw);
    }

    raw`Foo\nBar`;
    // ["Foo↵Bar"]
    // ["Foo\nBar"]

    console.log(String.raw('Foo\nBar'));
    // "Foo\nBar"
    
String.raw

Modules

Standardized module syntax, sync and async

Replaces CommonJS, AMD, and UMD

CommonJS-like syntax

How many are using a module system today? Which one?
Named Exports
    // foo.js
    export bar = (baz) => baz;
    export baz = (fum) => fum;
    
Default exports (favored)
    // foo.js
    let bar = (baz) => baz;
    let baz = (fum) => fum;
    export default { bar, baz };
    
Imports
    // default exports
    import foo from './foo';

    // named exports
    import { bar, baz } from './foo';

    // default + named exports
    import foo, { bar, baz } from './foo';

    // named exports as object
    import * as foo from './foo';

    // load module but don't import
    import './foo';
    

Module Loader API

Define, load, configure modules programmatically

Each host environment implements 'System'

    // load one module (with ES6 promises)
    System.import('myModule')
    .then(myModule => {
      // use myModule
    });

    // load multiple modules
    Promise.all(
      ['m1', 'm2', 'm3'].
      map(m => System.import(m)))
    .then(([m1, m2, m3]) => {
      // use m1, m2, m3
    });
    
    

Using ES6 modules today

Until loader API is implemented, build layer transpile/transform:

  • Browserify
  • WebPack
  • JSPM/SystemJS

Resources

questions?

Thanks!

Tim Doherty

@TimCDoherty

timdoherty.net