ES6/ES2015
Crash Course
let / const
are the new var
let - Better scoping
function varTest() {
  var x = 1;
  if (true) {
    // same variable!
    var x = 2;
    console.log(x); // 2
  }
  console.log(x); // 2
}function letTest() {
  let x = 1;
  if (true) {
    // different variable
    let x = 2;
    console.log(x); // 2
  }
  console.log(x); // 1
}let - Better scoping
var a = b + 1;
var b = 2;
console.log(a);
// NaN
let a = b + 1;
let b = 2;
console.log(a);
// ReferenceError: b is not defined
const
Not reassignable variables
const a = 2;
a = 100;
// TypeError: Assignment to constant variable.const
NOT Immutable!
const foo = {
  bar: 2
};
foo.bar = 100;
console.log(foo);
// => { bar: 100 }Arrow functions
Shorter way to write functions
// ES5 function declaration
function add(a, b) {
  return a + b;
}
// ES6 arrow functions
const add = (a, b) => a + b;Useful for small operations
array.filter(function(item) {
  return item.value > 100;
})
.map(function(item) {
  return item.value * item.value;
})
.reduce(function(res, value) {
  return res + value;
});
// versus
array
  .filter(item => item.value > 100)
  .map(item => item.value * item.value)
  .reduce((res, value) => res + value);Arrow functions syntax
// Parens needed when 0 or several parameters
() => 2;
(a, b) => a + b;
// Parens optional with one parameter
f => f(2);
(f) => f(2);
// Implicit return or block statement with explicit return
() => 2
() => { const a = 2; return a; }
// Can't name a function, but can assign to a variable (stack traces :+1:)
function foo() {}
const foo = () => {}
const foo = () => {
  a: 1,
  b: 2
};
foo() // => ?Arrow functions trap
const foo = () => {
  a: 1,
  b: 2
};
foo()
// => SyntaxError: Unexpected token :
const foo = () => ({
  a: 1,
  b: 2
});Bound to parent `this`
function foo() {
  this.bar = 1;
  const fn = () => {
    this.bar++;
  };
  fn();
  console.log(this.bar);
  // => 2
}
foo()Other subtleties
- Calling with `.call`/`.apply` does not change `this`
- No `arguments` object
- Will throw an error when called with `new`
Spread operator
and
Rest parameters
Spread operator
// Passes multiple args to a function
fn(...[1, 2, 3, 'foo']) === fn(1, 2, 3, 'foo');
// Simpler than `apply`
fn.apply(this, [1, 2, 3, 'foo']);
// Concatenates arrays
[1, 2, ...[3, 4, 5], 6]
// => [1, 2, 3, 4, 5, 6]
// ES proposal: merge objects
const object = { a: 1, b: 2 };
{...object, a: 500, z: 26}
// => { a: 500, b: 2, z: 26 }Rest parameters
Simpler `arguments`
foo(1, 2, 3, 4);
function foo(...args) {
  // args === [1, 2, 3, 4]
}
function foo(head, ...tail) {
  // head === 1
  // tail === [2, 3, 4]
}
// rest parameter is always last
function foo(...allButLast, last) {} // NoTemplate Literals
No more string concatenation
let type = 'normal';
'This is a ' + type + ' string';
type = 'template literal';
`This is a ${type} string`;
// => This is a template literal string
// Expressions
`Number ${n + 1}`;Multiline
console.log(`
  Lorem ipsum dolor sit amet,
  eum ea mucius causae reprimique,
  quo iusto nominati id.
`);
//
//  Lorem ipsum dolor sit amet,
//  eum ea mucius causae reprimique,
//  quo iusto nominati id.
//As functions
function format(template, ...expressions) {
    console.log(template);
    console.log(expressions);
    return {a: 1};
}
const food = 'Fish & Chips', n = 3;
format`Eat ${food} ${n} times a week`
// [ 'Eat ', ' ', ' times a week' ]
// [ 'Fish & Chips', 3 ]
// => {a: 1}As functions
// SQL query template
const query = SQL`SELECT * FROM books`
if (params.name) {
  query.append(SQL` WHERE name = ${params.name}`)
}
// GraphQL query template
const query = gql`
  {
    user(id: 5) {
      firstName
      lastName
    }
  }
`Destructuring
Get field values from objects
const object = {
  a: 1,
  b: 2
};
const {a} = object;
console.log(a);
// => 1
// Equivalent to
const a = object.a;
// Multiple destructuration
const {a, b, c} = object;
console.log(a, b, c);
// => 1, 2, undefinedMore in depth
// Rename fields - key AS name
const {a: variable} = object;
// Nesting
const {a: {b}} = {a: {b: 100}}
// === const b = 100;
// Will error as usual when accessing undefined values
const {c: {b}} = {a: {b: 100}} // BOOM
// Works for parameters too
const shoutUserName = ({name}) => name.toUpperCase();const [a, b] = [1, 2];
// a = 1, b = 2;
// Skip elements
const [a, , b] = [1, 2, 3, 4, 5];
// a = 1, b = 3;
// With spread operator
const [a, ...rest] = [1, 2, 3, 4, 5];
// a = 1, rest = [2, 3, 4, 5];
// Swap values
[a, b] = [b, a]Destructuring with arrays
Object literal syntax & computed property names
// Object literal syntax
const foo = 1, bar = 2;
const object = { foo, bar };
// Equivalent to
const object = { foo: foo, bar: bar };
// Also for functions
const object = {
  bar() {
    // do stuff
  }
}
object.bar();Object literal syntax
// Computed property names
const key = 'ok';
const object = {
  [key]: 100;
};
// Equivalent to
const object = {};
object[key] = 100;Computed property names
Iterators
Iterators
const iterator = ...;
iterator.next(); // {value: 1, done: false};
iterator.next(); // {value: 2, done: false};
iterator.next(); // {value: 3, done: false};
iterator.next(); // {done: true};
iterator.next(); // {done: true};
// ad vitam æternam...Iterators
const array = [];
for (let i of iterator) {
  array.push(i);
}
array
// [1, 2, 3]
[...iterator]
// [1, 2, 3]for loops
for (let i = 0; i < a.length; i++) {} // Manual
for (let i of iterator) {} // On iterators
// On keys of an object / items of an array
for (let key in object) {}
for each (let value in object) {} // On values of an objectCreate your own iterator?
const object = {
  __iterator__() {
     // ...
  }
};
// What if someone overrides that field...?Symbols
Symbols
const object = {
  array: [3],
  [Symbol.iterator]() {
    let nextIndex = 0;
    return {
       next() {
           if (nextIndex < this.array.length) {
             return {value: array[nextIndex++], done: false}
           }
           return {done: true};
       }
    };
  }
};
object.iterator // undefined
object[Symbol.iterator] // the iterator
for(let i of object) {
   // ...
}Symbols
const times2Symbol = Symbol('times2');
const object = {
  n: 3,
  [times2Symbol]() {
    return this.n * 2;
  }
};
object.times2Symbol; // undefined
object[times2Symbol](); // 6Generators
Functions that return multiple values
function* generator() {
  yield 1;
  yield 2;
  return 3;
}
const g = generator();
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 3, done: true }
g.next(); // { value: undefined, done: true }
Functions that return multiple values
function* generator() {
  yield 1;
  console.log(100);
  yield 2;
  console.log(200);
}
for (let item of generator()) {
  console.log(item);
}
// 1
// 100
// 2
// 200Functions that return multiple values
function* generator() {
  yield 1;
  yield 2;
  return 3;
}
[...generator()] // [1, 2]Proxies
const object = {};
const handler = {};
const proxy = new Proxy(object, handler);
proxy.a = 2;
console.log(object);
// => {a: 2}Proxies
const object = {
  a: 50
};
const handler = {
  get(target, key) {
    if (target[key] === undefined) {
      return 100;
    }
    return target[key];
  }
};
const proxy = new Proxy(object, handler);
proxy.a // => 50
proxy.b // => 100Proxies
const object = {
  a: 50
};
const handler = {
  set(target, key, value) {
    if (value >= 0) {
      target[key] = value;
      return true;
    }
    return false;
  }
};
const proxy = new Proxy(object, handler);
proxy.a = -5
proxy.a // => 50Proxies
const array = [1, 2, 3, 4, 5];
const handler = {
  get(target, index) {
    index = parseInt(index);
    if (index < 0) {
      index = target.length + index;
    }
    return target[index];
  }
};
const proxy = new Proxy(array, handler);
proxy[-1] // => 5
proxy[-2] // => 4Proxies
Map / Set
WeakMap / WeakSet
const user = {
  name: 'Some Name'
};
const userAgeMap = new Map()
userAgeMap.set(user, 20);
// => Map { { name: 'Some Name' } => 20 }
userAgeMap.get(user);
// => 20
[...userAgeMap]
// => [ [ { name: 'Some Name' }, 20 ] ]Map
const user = {
  name: 'Some Name'
};
const set = new Set();
set.add(user);
set.add(1);
set.add(user);
set.has(user);
// => true
[...set]
// => [ { name: 'Some Name' }, 1 ]Set
var map = new WeakMap()
// Only references, no primitives
map.set(1, 2)
// TypeError: 1 is not an object!
// Items can be removed by the garbage collectorWeakMap / WeakSet
Mo mo modules!
Static dependencies
import foo from './foo.js';
import {bar, baz} from './foo.js'
import fs, {readFile, writeFile as wf} from 'fs';
// foo.js
export default function() {}
export const baz = 2;
export {
  bar: 1,
  bloo: 2
};
Module import
// a.js
export {
  foo: 2
};
// b.js
// Wrong
import A from './a.js';
A.foo()
// Right
import {foo} from './a.js';
foo()Module
// Always top-level
import fs from 'fs';
// No conditional
if (condition) {
  import x from 'x'; // BOOM
}
// No variables (no loops)
import x from importName; // BOOMModule constraints
And a lot more
Native Promise
// Create a new Promise from scratch
new Promise(function(resolve, reject) {
  resolve('foo');
})
.then(function(value) { ... })
.catch(function(error) { ... });
// Resolve with value `foo`
Promise.resolve('foo');
// Reject with error `foo`
Promise.reject(new Error('foo'));
// Resolve when all promises have resolved
Promise.all([promises]);
// Resolve when the first promises resolves
Promise.race([promises]);function foo(a=1) {}
(a=1) => a + 1;
// Complex stuff!
function foo({ a=1, b=2 } = {a: 3}) {
  console.log(a, b);
}
foo() // 3, 2
foo({}) // 1, 2
foo({a: 100}) // 100, 2Default parameter value
class Ship extends Mothership {
  constructor() {
    this.message = 'classes';
  }
  // No commas!
  print() {
    return `I don't like ${this.message}.`;
  }
}Classes in Java(Script)
Object.assign({}, {a: 1, b: 2}, {a: 100})
// => {a: 100, b: 2}
array.find((n) => n === 2);
array.findIndex((n) => n === 2);
// Iterators
array.values(); // Not in Node v6
array.keys();
array.entries();New builtin methods
// Already in Node v6
array.includes(2) // === (array.indexOf(2) !== -1)
// Not in Node v6
2 ** 3 // === Math.pow(2, 3)
a **= 2 // === a = Math.pow(a, 2)
// That's itES7/ES2016
More reading
ES6 Crash Course
By Jeroen Engels
ES6 Crash Course
- 954
 
   
  