A Crash Course to ES6

Why ES6?

Modules

Promises

Classes

Destructuring

And more!

But it's not in the browser yet...

Compile future JS to browser compliant JS

Fat Arrows

// declare another variable in higher scope
function Counter() {
  this.time = 0;

  var self = this;
  setInterval(function() {
    self.time++;
  }, 1000);
}


// bind function to this
function Counter() {
  this.time = 0;

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

ES5

// lexical this with fat arrow
function Counter() {
  this.time = 0;

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

ES6

function double(array) {
  return array.map(function(item) {
    return item * 2;
  });
}

ES5

// fat arrow
function double(array) {
  return array.map((item) => {
    return item * 2;
  });
}

// one liner with implicit return
function double(array) {
  return array.map(item => item * 2);
}

ES6

Classes

function Animal(name) {
  this.name = name;
}

Animal.prototype.sleep = function() {
  console.log('zzZZ');
}

function Dog(name) {
}

Dog.prototype = new Animal();

var dog = new Dog();

dog.sleep(); // zzZZ

ES5

class Animal {
  constructor(name) {
    this.name = name;
  }

  sleep() {
    console.log('zzZZ');
  }
}

class Dog extends Animal {
}

var dog = new Dog();

dog.sleep(); // zzZZ

ES6

Destructuring

var object = {a: 2, b: 3, c: 4};

var a = object.a;
var b = object.b;
var c = object.c;

console.log(a, b, c); // 2 3 4

var array = ['a', 'b', 'c'];

var first = array[0];
var second = array[1];
var third = array[2];

console.log(first, second, third); // a b c

ES5

var object = {a: 2, b: 3, c: 4};

var {a, b, c} = object;

console.log(a, b, c); // 2 3 4

var array = ['a', 'b', 'c'];

var [first, second, third] = array;

console.log(first, second, third); // a b c

ES6

function pointLogger(point) {
  var x = point.x;
  var y = point.y;
  console.log(x, y);
}

ES5

function pointLogger({x, y}) {
  console.log(x, y);
}

ES6

Default/Rest/Spread

Parameters

function doStuff(arg1, arg2) {
  if (arg1 === undefined) {
    arg1 = 2;
  }
  if (arg3 === undefined) {
    arg2 = 2;
  }
  console.log(arg1, arg2);
}

doStuff(3); // 3 4

ES5

function doStuff(arg1 = 2, arg3 = 4) {
  console.log(arg1, arg2);
}

doStuff(3); // 3 4

ES6

Default Parameters

function log(first, ...rest) {
  console.log(first, rest);
}

log(3); // 3 []
log(3, 2, 'more'); // 3 [2, 'more']

Rest Parameter

function sum(x, y, y) {
  return x + y + z;
}
sum(...[1, 2, 3]); // 6

var obj1 = {a: 2, b: 3, c: 5};
var obj2 = {b: 4, d: 6};
var merged = {...obj1, ...obj2};
console.log(merged); // {a: 2, b: 4, c: 5, d: 6}

Spread Operator

Block Scope

function myFunc() {
  var lexicalScope = 2;
  if (lexicalScope === 2) {
    let blockScope = 5;
    console.log(blockScope, lexicalScope); // 5 2
  }
  console.log(blockScope, lexicalScope); // blockScope is not defined
}

let

const cantModifyMe = 2;
cantModifyMe = 4; // cantModifyMe is read-only

const

Modules

// helpers.js

export function func1() {}

export function func2() {}

export class Class1 {}

export var myVar = 2;

Named Exports

// main.js
import * as Helpers from 'helpers';
Helpers.func1();
Helpers.func2();


import {func1, func2} from 'helpers';
func1();
func2();
// helper.js

export default class Helper {
}

Default Export

// main.js
import Helper from 'helper';

var helper = new Helper();

import CallItSomethingElse from 'helper';

var anotherHelper = new CallItSomethingElse();
// helpers.js

export function func1() {}

export function func2() {}

export default class Class1 {}

export var myVar = 2;

Named and Default Exports

// main.js
import Class1, {func1, func2} from 'helpers';
func1();
func2();

var c = new Class1();

Promises

var promise = new Promise(function(resolve, reject) {
  var data = asyncGetDataFromServer();

  if (data.success) {
    resolve(data.num);
  }
  else {
    reject(Error('Server error'));
  }
});

promise.then(function(result) {
  console.log(result); // 5
}, function(error) {
  console.log(error); // Error: 'Server error'
});

promise.then(function(result) {
  console.log(result); // 5
}).catch(function(error) {
  console.log(error); // Error: 'Server error'
});

  

or


promise.then(function(result) {
  return result * 2;  // 5 * 2
}).then(function(result) {
  console.log(result);  // 10
});
Promise.all([promise1, promise2, promise3]).then(function() {
  // all resolved
}, function() {
  // one or more promises failed
});

Template Strings

var myVariable = 50;

console.log(`This is my variable: ${myVariable}`);
// This is my variable: 50

Comparison to CoffeeScript

Similarities

  • Fat arrow functions
  • Classes
  • Template strings
  • Destructuring
class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

sam = new Snake "Sammy the Python"

sam.move()

CoffeeScript

class Animal {
  constructor(name) {
    this.name = name;
  }

  move(meters) {
    alert(`${this.name} moved ${meters}m.`);
  } 
}

class Snake extends Animal {
  move() {
    alert('Slithering...');
    super.move(5);
  }
}

var sam = new Snake('Sammy the Python');
sam.move();

ES6

Exercises

Get the broken code to function as expected by using ES6 features that solve these problems

Refactor the example to make use of ES6 features

Additional Resources

A Crash Course to ES6

By Jonathan Lehman

A Crash Course to ES6

  • 1,842