Six from ES6

Classes

Classes arrive to JavaScript in ES6, here are a few notable features:

  • Initialization via 'constructor'
  • Easy inheritance with 'extends'

  • 'super()' to call parent classes
class Person {
    constructor(name) { //constructors!
        this.name = name;
    }

    introduction(){
        console.log("I'm " + this.name);
    }
}

class Worker extends Person { //inheritance
    constructor(name, profession) {
        super(name); //call the parent class with super
        this.profession = profession;
    }

    introduction(){
        super.introduction();
        console.log("I am a " + this.profession);
    }
}

var dev = new Worker("Dan", "Web Developer");

dev.introduction(); // logs: I'm Dan | I am a Web Developer

Arrow Functions

Managing scope gets easier in ES6, here's how arrow functions help:

  • External scope is retained by arrow function blocks
  • No need to store references on local variables for access within deeper function blocks

  • More streamlined than past APIs where a bind parameter can be passed as an argument. (Array forEach, map, etc.)

// Without arrow function

function TickTock() {
  var self = this; // locally assign var for 'this'
  self.seconds = 0;

  setInterval(function() {
    // this has a different scope, so we use 'self'
    console.log(++self.seconds + " seconds have passed");
  }, 1000);
}

// With arrow function

function TickTock() {
  this.seconds = 0;

  setInterval(() => {
    // now the outside scope of 'this' is retained
    console.log(++this.seconds + " seconds have passed");
  }, 1000);
}

Modules

JavaScript gets a legit module loader...finally:

  • Smooth refactoring from global code to modular code
  • Interoperability with existing JS module systems like AMD, CommonJS, and Node.js
  • Standardized protocol for sharing libraries
  • Compatibility with browser and non-browser environments
  • Asynchronous external loading

/* ------ lib.js ------ */

export function square(x) {
    return x * x;
}


/* ------ main.js ------ */

import { square } from 'lib';
console.log(square(11)); // 121

Block Scoping

Block scoped variables help keep code in its place:

  • New 'let' variable keyword
  • Scopes to the nearest, enclosing block, not just within functions or on the global object.

var num = 0; // num is globally scoped

for (let i = 0; i < 10; i++) { // i is block scoped
  num += i;
  console.log('value of i in block: ' + i);
}

console.log(typeof i); // undefined

Template Strings

Templating has moved beyond vanilla strings and custom user functions:

  • Multi-line strings with: `
  • Code values into strings via replacer syntax: ${}
  • Embedded computation inside template strings

var transaction = {
    customer: "Jane",
    product: "sandwich",
    price: 8,
    sale: true
};

function printTransaction(obj){
  return `Hello ${obj.customer}, 
    do you want to buy this ${obj.product} 
    for ${obj.price * (obj.sale ? 0.75 : 1)} dollars?`;
}

printTransaction(transaction);

Proxies

React to, and manipulate, object accessors with custom logic:

  • Catch all get/set access
  • Not limited to predefined accessors/keys

var obj = {};
var count = 0;
var myNameIs = new Proxy(obj, {
    get (receiver, key) {
        if (count > 3) return "You are out of chances!"
        else {
            count++;
            return key.toLowerCase() == "rumpelstiltskin" ? 
                  "How did you guess!?!" :
                  "That's not my name."
        }
    }
});

var g1 = myNameIs.bob; // "That's not my name."
var g2 = myNameIs.tracy; // "That's not my name."
var g3 = myNameIs.rumpelstiltskin; // "How did you guess!?!"

Six from ES6

By Daniel Buchner

Six from ES6

  • 1,538