ES6 Features

Let and Const

Using var

function test() {
  foo = 2;
 
  for (var i = 0; i < 5; ++i) {
    var foo = i;
  }
}
 
test();
console.log(foo); // foo is not defined

But if you using let

function test() {
  foo = 2;
 
  for (var i = 0; i < 5; ++i) {
    let foo = i;
  }
}
 
test();
console.log(foo); // 2

Using const

var foo = 3;
foo = ['abc', 'def']; // foo is now bound to an array object
 
const bar = 3;
bar = ['abc', 'def']; // TypeError: assignment to const variable

Arrow functions and lexical this

[5, 10, 15, 20]
  .forEach(function(number, ind) {
    console.log(number);
  })
 
  [
    // Using arrow functions
    (5, 10, 15, 20)
  ].forEach((number, ind) => {
    console.log(number);
  });

Classes

class Vehicle {
  constructor(type, color) {
    this.type = type;
    this.color = color;
  }
 
  get Color() {
    return color;
  }
}

Object-literal Improvements

function getLaptop(make, model, year) {
  return {
    make,
    model,
    year
  };
}
 
getLaptop('Apple', 'Macbook', '2014'); // { make: 'Apple', model: 'Macbook', year: '2014' }

Template String Literals

var city = 'Sai Gon';
var str = 'I bike around ' + city;
 
let newStr = 'I bike around ${city}';

Generators, iterators, iterables and for…of

Generators

function* Counter() {
  let i = 0;
 
  while (true) {
    const reset = yield i++;
    if (reset) {
      i = 0;
    }
  }
}
 
const gen = Counter();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next(true).value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

Iterators

function arrayIterator(arr) {
  var i = 0;
  return {
    next: function() {
      return arr[i++];
    },
    ended: i >= arr.length,
    reset: function() {
      i = 0;
    }
  };
}
 
var data = [0, 1, 2, 3, 4];
var iter = arrayIterator(data);
console.log(iter.next()); // 0
console.log(iter.next()); // 1
console.log(iter.next()); // 2

Default Arguments and the Rest Operator

function request(url, method = 'GET') {
  // Todo
}
function manyArgs(a, b, ...args) {
  // args = ['Hello', 'World', true]
}
 
manyArgs(1, 2, 'Hello', 'World', true);

Spread Syntax

const first = [1, 2, 3, 4];
const seconds = [-2, -1, 0, ...first, 5, 6, 7];
 
const arrCopy = [...first]; // [1, 2, 3, 4]

Destructuring

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

Modules

Collections

Set, Map, WeakSet, WeakMap

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
 
// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
 
// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
 
// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });

Object Proxies

// Proxying a normal object
var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}!`;
  }
};
 
var p = new Proxy(target, handler);
p.world === 'Hello, world!';
 
// Proxying a function object
var target = function () { return 'I am the target'; };
var handler = {
  apply: function (receiver, ...args) {
    return 'I am the proxy';
  }
};
 
var p = new Proxy(target, handler);
p() === 'I am the proxy';

Symbols

var MyClass = (function() {
 
  // module scoped symbol
  var key = Symbol("key");
 
  function MyClass(privateData) {
    this[key] = privateData;
  }
 
  MyClass.prototype = {
    doStuff: function() {
      ... this[key] ...
    }
  };
 
  return MyClass;
})();
 
var c = new MyClass("hello")
c["key"] === undefined