Menu

Preview of ES6

Who's excited for ES6? Hold on to your socks. Here is a sneak peek of what's to come in ECMAScript 6.

let and const

let can be used to declare variables just like var, but let has no hoisting, it has lexical scoping within () and {} blocks, and you cannot redeclare a variable that was declared with let.

for (let i = 0; i < 3; i++) {  
  console.log(i); // logs 0, 1, and 2
}
console.log(i); // throws an error  

const is like let, but you cannot reassign a value.

const pi = 3.14;  
pi = 3; // throws an error  

Arrow Functions

This is very much like CoffeeScript, except there is only fat arrow (=>), and no regular arrow (->).

// ES6 way
let fn = (a, b, c) => {  
  console.log(a, b, c);
  return true;
};

fn(1, 2, 3); // logs "1 2 3" and returns true

// ES5 way
var fn = function(a, b, c) {  
  console.log(a, b, c);
  return true;
};

And just like CoffeeScript, the fat arrow will automatically bind the function to the current value of this during declaration.

// ES6 way
let Human = (age) => {  
  this.age = age || 0;
  setInterval(() => {
    this.age++; // `this` will properly refer to the Human object
  }, 1000);
};

// ES5 way
var Human = function(age) {  
  var self = this;
  self.age = age || 0;
  setInterval(function() {
    self.age++;
  }, 1000);
};

Another thing to point out is that if the function body is just one line, there will be an implicit return. The two functions below do the same thing.

let add10 = (x) => x + 10;

let addTen = (x) => {  
  return x + 10;
};

Classes

Classes are how you can implement inheritance in ES6. Unlike function declarations, class declarations are not hoisted, so a class must be declared before attempting to access it.

class Human {  
  constructor(name, diet) {
    this.name = name;
    this.diet = diet;
  }
  report() {
    return this.name;
  }
}

class Omnivore extends Human {  
  constructor(name) {
    super(name, "omnivore");
  }
  report() {
    return super.report() + ": I eat everything!";
  }
}

class Vegetarian extends Human {  
  constructor(name) {
    super(name, "vegetarian");
  }
  report() {
    return super.report() + ": I don't eat meat";
  }
}

let meatLover = new Omnivore("Mary");  
console.log(meatLover.report()); // logs "Mary: I eat everything!"  
let meatHater = new Vegetarian("Ellen");  
console.log(meatHater.report()); // logs "Ellen: I don't eat meat"  

Also notice how the report method doesn't need a let or var in front of it. It's automatically recognized as a method.

Template Strings

Use backticks instead of single or double quotes to embed expressions within strings and create string interpolation.

var a = 1;  
var b = 2;  
console.log(`${a} + ${b} = ${a + b}`); // logs "1 + 2 = 3"  

Spread Operator

If you want an easy way to expand an expression in function calls or array literals, use the spread operator, ....

let nums1 = [1,2,3];  
let nums2 = [4,5,6];  
console.log(...nums1) // logs "1 2 3"  
let nums = [...nums1, ...nums2];  
console.log(nums); // logs "1,2,3,4,5,6"

var print = (a, b, c, d, e) => {  
  console.log(a, b, c, d, e);
};
var args = [2, 3];  
print(1, ...args, 4, ...[5]); // logs "1 2 3 4 5"  

Rest Parameters

Prefixing the last named argument of a function with ... will allow you to represent an indefinite number of arguments as an array.

There are some differences between rest parameters and the arguments object.

  • Rest parameters are only the ones not given a separate name, while the arguments object contains all arguments passed to the function
  • The arguments object is not a real array, while rest parameters are Array instances, so you can use native Array methods on it
  • The arguments object has additional functionality specific to itself (like the callee property)
let logNums = (first, second, third, ...others) => {  
  console.log(first, second, third, others) // logs "1 2 3 4,5,6,7,8"
  console.log(others) // logs "4,5,6,7,8"
  console.log(others.map(function(num) {
    return num * 2;
  })); // logs "8,10,12,14,16"
};
logNums(1,2,3,4,5,6,7,8);  

Default Parameters

Now you can define default values to use for function parameters if no value or undefined is passed. By default, if no value is passed, JavaScript will set the parameter value to undefined, but you can now use your own default value.

let multiply = (x, y = 1) => x * y;  
console.log(multiply(4)); // logs "4"  

Not the End

This is just a taste of what's to come in ES6. There are many more features I didn't mention. It's going to be interesting seeing how companies and the community go about adopting ES6. Are your socks still on?