JavaScript 6 - ECMASCript 6 - ES 2015

Variables and Parameters

Let

The new let keyword allows you to define block-scoped variables in JavaScript(As opposed to function scoped variables that we have had so far in JavaScript). let is not only useful for its block scope but it also solves the hoisting problem inherent to var.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// traditional JavaScript with var
function print(something){
    // var x = undefined; (var is hoisting the x variable 
    // to the top of the function body since var defines 
    // function scoped variables)
    if (doPrint) {
      var x = "jaime";
    }
    console.log(something, x);
}
print("hello"); // => hello jaime

// ES2015 with let
function printFive(doPrint){
    if (doPrint){
      let x = "jaime";
    }
    console.log(x);
}
print("hello"); // => Reference Error
// Awesome example where using let throws a reference errors 
// because the variable x only exists within the if block, Good job XDDD

Const

const lets you define constant ‘variables’ with block scope. If you try to assign a new value to a const you will get a SyntaxError.

Destructuring Assignment

The new destructuring assignment syntax allows us to extract parts of arrays and objects into variables using a syntax similar to the one we nowadays use to create arrays an objects.

For instace, we can destructure an array like this:

1
2
3
var [a,b] = [1,2]
console.log(a); // => 1
console.log(b); // => 2

And you can even destructure an array that is passed to a function:

1
2
3
4
5
function([a,b]){
    console.log(a);
    console.log(b);
}
function([1,2]); // => 1, 2

You can also destructure objects:

1
2
3
4
5
6
var { race,
      charClass } = { race: 'human',
                      charClass: 'barbarian',
                      origin: 'summeria'};
console.log(race); // => 'human'
console.log(charClass); // => 'barbarian'

The destructuring assignment syntax also allows you to define different variables names than the original property names:

1
2
3
4
5
6
7
8
9
10
11
12
13
// This is interesting, the syntax used is the opposite
// to what we are accustomed to when using object literals
// the first part 'race' is the property we want to destructure
// in the original object whiles the second part 'cucumber'
// is the name of the new variable

var { race: { cucumber },
      charClass: { orange } } = { race: 'human',
                      charClass: 'barbarian',
                      origin: 'summeria'};

console.log(cucumber); // => 'human'
console.log(organe); // => 'barbarian'

And if you need to go deeper within an object structure you can very well do it:

1
2
3
4
5
6
7
8
var { race: { cucumber },
      equipment: { righthand: weapon}} = { race: 'human',
                      charClass: 'barbarian',
                      origin: 'summeria',
                      equipment: { righthand: "Krom's sword"}};

console.log(cucumber); // => 'human'
console.log(weapon); // => Krom's sword

Like with arrays, you can also use destructuring with objects that are passed as arguments:

1
2
3
4
5
6
7
8
9
// in ES<6
function print(message, options){
    var inColor = options.inColor,
        twoSides = options.twoSides, etc...;
}
// in ES6
function print(message, {inColor, twoSides, ...}){
    //...
}

Default Parameter Values

ES6 finally brings default parameters to JavaScript, what we have been achieving until this point like this:

1
2
3
4
5
6
7
var never = false,
    always = true;

function print(message, options){
    var inColor = options.inColor || never,
        twoSides = options.twoSides || always;
}

We can now achieve with standard ES6:

1
2
3
4
5
6
const never = false,
      always = true;

function print(message, {inColor=never, twoSides=always}){
   ...
}

Note that the default parameter values only works when an argument is not passed to a function (i.e. it is undefined), and not for all falsey values.

Spread Operator

The rest parameters syntax allows us to wrap a series of arguments within a single variable (like params in JavaScript and similar to the arguments array-like object in JavaScript).

Traditionally in JavaScript, whenever we have a function that can take any number of arguments we have used the arguments array-like object:

1
2
3
4
5
6
7
8
function print(){
    var messages = Array.prototype.slice.call(arguments,0);
    messages.forEach(function(msg){console.log(msg);});
}
print("hello", "lalalala", "yippi");
// => hello
// => lalalala
// => yippi

From now on we will be able to use the rest syntax ...:

1
2
3
4
5
function print(...messages){
    messages.forEach(function(msg){console.log(msg);});
}
// and another example
function print()

Which defaults to an empty array [] when no arguments are provided.

Spread Operator

The spread operator unwraps, spreads or extends an expression into several arguments (within functions) or elements (within arrays):

1
2
3
4
5
6
7
// spread array into arguments
function add(x,y,x){ return x+y+z;}
add(...[1,2,3]);// => 6

// spread array into array elements
var subArray = [2,2,2];
var array = [1, 2, ...subArray, 3, 4, 5];

Template literals

ES6 finally gets template literals for generated templated strings:

1
2
3
4
5
6
7
// what we use to do like this
function sayHi(firstName, lastName){ console.log("Hi my friend " + firstName + " " + lastName);}

// no we can do like this
function sayHi(fisrtName, lastName){ console.log(`Hi my friend ${firstName} ${lastName}`);}

// Note that the template literal uses backtick `` instead of quotes

The different variables to inject in a template are evaluated in the scope where the template literal is declared. Additionally we are not limited to using variables but can also use any valid expression.

The templating engine also allows to define custom formatting functions known as tags filters that can be applied to the template literals to customize the formatting process:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// example from MDN
var a = 5, b = 10;

// where strings are the different parts of the template literal
// and values are the variables been injected in the template
function tag(strings, ...values) {
  console.log(strings[0]); // "Hello "
  console.log(strings[1]); // " world "
  console.log(values[0]);  // 15
  console.log(values[1]);  // 50

  return "Bazinga!";
}

tag `Hello ${ a + b } world ${ a * b}`;
// "Bazinga!"

Classes

Functional JavaScript

Built-in objects

Asynchronous Programming in ES2015

ES2015 Objects

ES2015 Modules

How to Start Writing ES2015 Today

Traceur

You can use traceur at plunkr by adding a reference to traceur.js, the traceur bootstrapper and including script tags with the type="module".

Playground

  • TDDBin supports ES6 and allows you to play with code using a TDD approach.

References

Comments