ES6 features in io.js

The latest version of io.js is 2.1.0 and supports quite a few ES6 (er, ES2015) features.

Note: if you want to keep versions of both Node and io.js on your system, try using nvm.

The good news with io.js is that ES6 features are available by default:

  • No runtime flag required
  • But make sure to add "use strict" to top of module

I created a repo that demonstrates these features using unit tests. This post provides an overview, but for more examples you should refer to the repo.

The repo also has a PDF version of the slides I used to present these features as part of io.js evangelism. You can also download the slides ("io.js 2.0 ES6 Features slide deck") from the official io.js evangelism wiki.


Block scoping features

let

Get used to it. Use it instead of var.

  • declares a block scope local variable
  • optionally initialized to a value
  • eliminates weirdness due to var hoisting
let var1 = value1;  

const

  • creates a read-only named constant
const name1 = value1  

Function in blocks

You could always create a function inside of a function scope. Now you can create a function inside of block scope as well

it ('greet function declared in two different scopes (function in block)', function() {

  function greet() {
    return 'woof';
  }

  if (true) {
    // function defined inside block
    function greet() {
      return 'meow';
    }

    assert.equal(greet(), 'meow');
  }

  assert.equal(greet(), 'woof');

});

Collections

  • Map
  • WeakMap
  • Set
  • WeakSet

Map

  • simple key/value map, iterates in order entries were added
  • keys can be any object, not just string
  • advantages of map over object
    • object has a prototype with default keys
    • object keys must be strings
    • can easily get the size of a map

Map Reference on Mozilla

Common Functions

  • get(key) / set(key, value)
  • has(key)
  • keys(), values()
  • delete(key), clear()

Common Properties

  • size

Iteration

let map = new Map();  
  • by values
      map.forEach(function(value) {
        ...  
      });
  • by key-value pairs
      for (let pair of map) {
        // pair is an array [ key, value ]
      }
  • by pairs using an iterator function
      let entries = map.entries();
      let entry = entries.next();
      // entry.done
      // entry.value[0] => key
      // entry.value[1] => value
  • by keys using an iterator function
  let keys = map.keys();
  let next = keys.next();
  // next.value
  // next.done
  • or by keys using a for-of loop
  for (let key of map.keys()) {
  }
  • or by values using an iterator function
  let values = map.values();
  let next = values.next();
  // next.value
  // next.done
  • or by values using a for-of loop
  for (let value of map.values()) {
  }

WeakMap

Use when you don't want to prevent garbage collection when there are no other references to an object other than the key.

  • collection of key/value pairs
  • keys must be objects
  • keys are not enumerable

WeakMap reference on Mozilla

Set

A collection of unique values of any type.

  • can store undefined
  • can store NaA (will only store one instance even though NaN !== NaN)
  • iterates in insertion order

Set reference on Mozilla

Common Functions

  • add(value)
  • has(key)
  • values(), keys()
  • delete(key), clear()

Common Properties

  • size

WeakSet

A collection of weakly held objects

  • elements must be objects
  • elements are not enumerable

WeakSet reference on Mozilla

Generators

function* defines a generator function, which returns a Generator object.

  • simplifies iteration using yield to return a value (or throw an error) back to caller
function* name([param[, param[, ... param]]]) {  
   statements
}

Simple generator to yield 3 values:

function* gen() {  
  yield 1;
  yield 2;
  yield 3;
}

var g = gen(); // "Generator { }"  

Generator reference on Mozilla

Promises

Promise

  • a promise represents a pending value that will be provided in the future
  • a pending promise becomes settled when it is fulfilled (succeeds) with a value or rejected (fails) with a reason
  • alternative to using callbacks for asynchronous programming

Promisify function that expects a callback

Wrap function in another function that returns a Promise

function promiseFunc(arg) {

   return new Promise(function (resolve, reject) {

     asyncFunc(arg, function (err, result) {

       return err ? reject(err) : resolve(result);

     });

   });
 }

I published promisify-iojs to simplify promisifying standard callback-based functions. You can use it to promisify any idiomatic async function or module.

Calling promisified function

Provide then and catch handlers
Can chain then handlers

promiseFunc(arg)  
    .then(function (result) {
      ...
    })
    .catch(function (err) {
      ...
    });

Same thing but with "fat" arrow functions (more details in a later section).

promiseFunc(arg)  
    .then((result) => {
      ...
    })
    .catch((err) => {
      ...
    });

Classes

  • syntactic sugar over prototype-based OOP model
    • inheritance
    • constructor
    • super
    • static
    • get / set methods

See the repo for examples.

ES6 features that still need flags

Arrow functions

Finally ... this works the way people expect!

Need to pass the __harmony_arrow_function option

    iojs --harmony_arrow_functions index.js

or

    mocha -- --harmony_arrow_functions

Example

The way this works normally (without arrow functions) using bind:

function Person(){  
  this.age = 0;

  setInterval(function()  {
    this.age++;
  }.bind(this), 1000);
}

var p = new Person();  

The way this works normally (without arrow functions) using a closure (that closes over this):

function Person(){  
  var that = this;

  this.age = 0;

  setInterval(function() {
    that.age++;
  }.bind(this), 1000);
}

var p = new Person();  

The way this works with arrow functions:

function Person(){  
  this.age = 0;

  setInterval(() => {
    this.age++;
  }, 1000);
}

var p = new Person();  

Not covered here


Resources

https://github.com/tonypujals/demo-iojs-es6

https://iojs.org/en/es6.html

http://davidwalsh.name/es6-io

https://github.com/lukehoban/es6features

http://www.2ality.com

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols