ES6 workshop

Contents

  • let and const
  • Template literals
  • Enhanced object literals
  • Object destructuring
  • Rest operator
  • Spread syntax
  • Arrow functions
  • Symbols
  • Set and Map
  • Iterators
  • Generators
  • Proxies

 

Short history

  • 1995
    • May - Mocha invented by Brendan Eich  at Netscape (in 10 days!)
    • September - renamed to LiveScript
    • December - renamed to JavaScript (because JAVA...)
  • 1996 - ECMA takes JavaScript to standardization
  • 1997 - ECMA-262 (ECMAScript)
  • 1998 - ECMAScript 2
  • 1999 - ECMAScript 3
  • 2005 - Mozilla and Macromedia began to work on ECMAScript 4 - never released => ECMAScript 3.1
  • 2009 - ES5 emerges from previous discussions
  • 2015 - ES6 standard
    • Version names based on year of release (ES2015, ES2016

let and const

  • var is function scoped, cons and let are block (lexical) scoped

  • var declarations are hoisted to the top of the function
  • let declarations hoisted to the top of the block but cannot be used before initialization (temporal dead zone) 
  • const declarations must be initialized 
  • let and const cannot be redeclared
  • let allows for reassignment, const does not (not the same as immutable - for immutability we can use Object.freeze and/or Object.seal)

Template literals

  • string literals that allow embedded expressions
  • back-ticks (`) are used to enclose the string
  • anything inside ${} is evaluated
  • new lines are retained
  • tag templates - customize the resulting output string - useful for l10n/i18n or html sanitising 

Enhanced object literals

  • property initializer shorthand

  • concise method names

  • computed property names

  • new Object methods

    • Object.is() - make up for the remaining quirks of the identically equals operator

    • Object.assign(receiver, suppliers) - copy properties from supplier into receiver

    • Object.getOwnPropertyNames() - return all properties of an object (as opposed to only enumerable for Object.keys())

Object destructuring

  • de-structure a target objects' properties

  • works on all objects (including arrays)

  • can have default values for undefined properties 

  • default values evaluation is similar to a list of let variables declaration 

Rest operator

  • rest parameters for functions and rest items for arrays

  • use the ... operator to:

    • represent an indefinite number of function parameters as an array

    • to assign remaining values in an array to a particular value

Spread syntax

  • allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables  (for destructuring assignment) are expected

  • a replacement for apply

  • easier array operations

  • easier copy operation for arrays and objects

Arrow functions

  • shorthand for the function expression

  • does not bind its own this, arguments, super or new.target

  • preserves the 'this' of the calling location

  • best suited for non-method functions

  • are always anonymous

  • cannot be used as constructors and do not have a prototype

  • does not bind to an arguments object -> use rest params

Recap

function() {
  if(true) {
    var x = 1;
  }
  console.log(x) // 1
}

Block level scoping: const and let

function() {
  for(var i=0;i< 10;i++) {
    var x = 1;
  }
  console.log(i) // 10
  console.log(x) // 1
}
function() {
  if(true) {
    let x = 1;
  }
  console.log(x) // x doesn't exist here
}
function() {
  let x = 1;
  if(true) {
    let x = 2; // error cannot reasign
  }
}
function() {
  const a; // error, need to initialize const
  const b = 1;
  b = 2; // error cannot reasign
}
function() {
  for(var i=0; i<10; i++) {
    let x = 1;
  }
  console.log(i, x) // i, x don't exist here
}

Recap

var firstName = "Andrei",
    lastName = "Antal";

var fullName = "The full name is: " + firstName + " " + lastName

Template strings

var fullName = `The full name is: ${firstName} ${lastName}`;
function() {
  return (new Date()).year;
}

var currentYear = `The cuurent Year is ${getYear()}`;

var theSum = `The sum is ${3 + 4 / 2}`;
const theString = upp`Hello ${firstName} ${lastName}!`;

function upp(literal, name, name2) {
  return [
    literal[0],
    name,
    literal[1],
    name2.toUpperCase(),
    literal[2],
  ].join("");
}

Recap

const name = "Andrei";
const age = 29;

const user1 = {
  name: name,
  age: age,
  sayHello: function() {
    console.log("Yo!");
  }
}

Enhanced object literals

const user2 = {
  name,
  age,
  sayHello() {
    console.log("Yo!");
  }
}
const firstName = "first name";
const suffix = " name";

const person = {
  [firstName]: "Andrei",
  ["last" + suffix]: "Antal"
};
const obj1 = {
  a: 'a',
  b: 'b',
};
const obj2 = { b: 'c' };

Object.assign(obj1, obj2); // obj1 = { a: 'a', b: 'c' }
Object.assign({}, obj1, obj2); //  { a: 'a', b: 'c' }

Recap

let options = {
  repeat: true,
  save: false
};

let repeat = options.repeat;
let save = options.save;

Destructuring

let {repeat, save} = options;

console.log(repeat); // true
console.log(save); // false
let {repeat: re, save: sa, stop: st = false} = options;

console.log(re, sa, st); // true, false, false
let [one, two, three] = [1,2,3];
console.log(one, two, three); // 1,2,3

let [, , three] = [1,2,3];
console.log(three); // 3

Recap

const animal = {
  name: 'Dog',
  sound: 'wof'
};

function makeSound(options) {
  options.name = options.name || 'animal';
  console.log(`The ${options.animal} goes ${options.sound}`)
}

Destructuring


function makeSound({name = 'animal', sound}) {
  console.log(`The ${name} goes ${sound}`)
}

makeSound(animal);

Recap

function doSomething(a,b, ...rest) {
  console.log(a);
  console.log(b);
  console.log(rest);
}

doSomething(1,2,3,4,5); // 1, 2, [3,4,5]

function doSomething(a,b, ...rest, c){} // error; rest must be the last in param list

Rest operator

const arr = [1, 2, 3, 4, 5];

const [,, ...arr1] = arr;

console.log(arr1); // [3, 4, 5]
function doSomething(a,b, ...[c,d,e]){
  console.log(a);
  console.log(b);
  console.log(c,d,e);
}

doSomething(1,2,3,4,5); 

Recap

function logNumbers(a, b, c) {
  console.log(a)
  console.log(b)
  console.log(c)
}

const array = [1,2,3];

logNumbers(...array);

Spread

const array = [1,2,3];

console.log([...array, 4, 5]);
const obj1 = {a: 'a', b: 'b'};
const obj2 = {c: 'c', ...obj1};

console.log(obj2);
const arr1 = [1,2,3];
const arr2 = [2,3,4];

const arr3 = [...arr1, 8, ...arr2];
console.log(arr3);

Recap

const sum = (num1, num2) => { return num1 + num2 };

const sum = function(num1, num2) {
    return num1 + num2;
};

Arrow functions

const square = value => value * value;

const square = function(value) {
  return value * value;
};
const getName = () => "Andrei";

const getName = function() {
    return "Andrei";
};
const getTempItem = (id) => ({ id: id, name: "Temp" });

const getTempItem = function(id) {
    return {
        id: id,
        name: "Temp"
    };
};

Recap

const sum = (num1, num2) => { return num1 + num2 };

const sum = function(num1, num2) {
    return num1 + num2;
};

Arrow functions

const square = value => value * value;

const square = function(value) {
  return value * value;
};
const getName = () => "Andrei";

const getName = function() {
    return "Andrei";
};
const getTempItem = (id) => ({ id: id, name: "Temp" });

const getTempItem = function(id) {
    return {
        id: id,
        name: "Temp"
    };
};

Classes

  • syntactic sugar over over JavaScript's existing prototype-based inheritance - does not create a new object oriented inheritance model

  • classes are defined using the class keyword

  • class declarations are not hoisted

  • a class contains
    • constructor - class initialization
    • methods (we can also create also static methods)
    • properties (only using getters)
  • we can create hierarchies using the extends keyword
  • we ca use super() to call an object's parent

Symbols

  • a primitive (value) data type whose instances are unique and immutable

  • for debugging purposes symbols can have an optional description - stored in the [[Description]] property

  • symbols do not have a literal form, so they do not coerce into other primitive types

  • mostly used to create private properties - symbol keys are not visible in iterations

  • ES6 provides a global symbol registry in order to share symbols across the app

Set and Map

  • extra data types for working with collections (besides the Array data type)

  • can store primitive or object values

  • Set - iterable list of objects that cannot contain duplicates; elements are set in the insertion order

  • Map - iterable key/value pair entries list - keys can be objects, symbols, primitives and functions

  • WeakMap, WeakSet - non enumerable versions where keys/entries are referenced weakly - can be garbage collected if they aren't referenced elswhere

Iterators

  • iterators - objects with special interfaces designed for iteration
  • affects behaviour in for...of loops and the ... operator
  • the iterable protocol - customize iteration behaviour
    • implement @@iterator method (or [Symbol.iterator]) that returns an iterator
  • the iterator protocol - implement a next() method that returns an object with 2 keys:
    • value - current value in iteration
    • done - boolean (true when there are no more items in the enumeration)

Generators

  • generator - object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.

  • declared by adding a "*" between function and the name

  • use the yield keyword to denote execution halt until the next() method is called

  • each yield return an iteration (value, done) object

Proxies

  • proxy objects are used to define custom behavior for fundamental operations

  • create a proxy to use in place of another object (called the target)

  • intercept low-level object operations on the target (using a trap) that are otherwise internal to the JavaScript engine

  • use the Proxy constructor to make a proxy - pass it two arguments: the target and a handler (an object that defines one or more traps)

Other ES stuff

  • module system

  • native promises

  • tail call optimization

ES6 workshop

By Andrei Antal

ES6 workshop

  • 1,232