ECMAScript 6 – The future of JavaScript

After the current standard, ECMAScript 5, was primarily aimed at making it easier to develop bigger and more sophisticated software in ECMAScript (strict mode, getters and setters, property descriptor maps, …), the 6th version is shaping up follow the trails of its predecessor. Especially the addition of features such as classes and modules will enhance the programming experience with the various ECMAScript dialects (JavaScript, JScript, ActionScript) even further and provide developers with possibilities they longed for since the days JavaScript excelled its ‘5-lines-scripts’-nature. Still scheduled for a final specification by the end of 2013 it is time to look at the features ECMAScript 6 will introduce because they will likely have a huge impact on how developers will write code using JavaScript and friends. Please have in mind that the specification is by no means final and that some aspects may very well change significantly. There is also no guarantee that the code examples provided here will still be appropriate once the specification is finished.

History and current work

After the first three versions of the ECMAScript specification were released from 1997 to 1999, the progress slowed down pretty badly. Due to the increasing popularity of JavaScript in the mid 2000´s, some of the people that are in charge of the specification (Ecma International´s Technical Committee 39 ) thought that the language needed a major overhaul in order to fulfill its recently acquired role as the language of choice for web development. Unfortunately even after several years the committee could not agree on a specification for ECMAScript 4 (or short ES4) because some people felt that the changes and additions to the language would be too drastically. In 2008 it was decided to drop ES4 completely with some of the features that were planned for ES4 being delayed to ‘Project Harmony’. ES5 and ES5.1 were smaller releases (although version 5 introduced some very nice features) and ‘Project Harmony’ evolved into ‘ES.next’ aka ‘ES6’.

Browser compatibility

It is no surprise that the browser support has a lot room to improve to put it mildly, because most features are still in some kind of “work in progress” status. Nevertheless some of the more stable features (like ‘let’ or ‘const’) already enjoy support by various browsers. Detailed information can be found at this detailed reference. (http://kangax.github.com/es5-compat-table/es6/)

Features of ECMAScript 6

The corresponding wiki page describes the main goals of ECMAScript 6 as follows: “Be a better language for writing:

  • complex applications
  • libraries[…]
  • code generators[…]”

Let´s see which features are meant to fulfill those promises:

Classes

Although inheritance can be implemented in JavaScript using the “prototype” feature, the inclusion of real classes is something many developers desired for a long time. The final decisions on this topic have not been made it seems by the TC39 as the first proposal for classes was rejected and replaced by a more minimalistic approach. How does the current specification look like?

class Car extends SomeClass {

    // simply create a method named "constructor" to create
    // a constructor function for the class
    constructor(brand, color, year) {
        this.brand = brand;
        this.color = color;
        this.year = year;
        this.speed = 0;
    }

    // simply create object functions/methods
    accelerate() {
        this.speed += 10;
    }

    brake() {
        if(this.speed >= 10) {
            this.speed -=10;
        }
    }

    // getter and setters can be declared like
    // in object literals
    get speed() {
        return this.speed;
    }

    set speed(newSpeed) {
        this.speed = newSpeed;
    }
}  

Modules

The module pattern is probably one of the most common coding patterns for JavaScript, especially for framework developers. But although the pattern is in heavy use, it is in fact only a workaround because JavaScript didn´t feature a standardized module system until now. The declaration of a module is pretty straight forward:

module "foo" {
    // code...
}  

If you want to make certain functions or variables/constants available to other modules, you can achieve this by assigning the “export” keyword.

module "superLongModuleName" {
    export const num = 42;
    export function add(x, y) {
        return x + y;
    }
}  

You can than either import a whole module (and give it an alias)…

import "superLongModuleName" as mod;
console.log(mod.num) // 42;

…or you can only include the functions and variables you are interested in.

import {num, add} from "superLongModuleName";
console.log(add(num, num)); // 84

Block-scoped variables

It is only one of JavaScripts weird quirks that there is no block scope and variables defined in a block are also visible outside of these blocks.

function foo() {
    if(true) {
        var bar = 10;
    }

    console.log(bar);   // prints 10
}  

Therefore ES6 introduces ‘let’ which is the keyword to declare a block-scoped variable.

if(true) {
    let bar = 10;
}
console.log(bar);   // undefined

// also applicable in for-loops
for(let foo = 0; foo < 10; foo++) {
    // do something...
}
console.log(foo);   // undefined  

David Herman from Mozilla even proclaims that “let is the new var” and that there is no reason to use “var” in new developments at all.

Constants

With the property descriptor maps introduced in ES5 it was already possible to prevent object properties to be changed after creation. However, this approach has two drawbacks as it can result in a lot of boilerplate-code and because it is not applicable for simple variables (outside of an object). The new ‘const’ keyword, probably adopted from C/C++, lets you simply declare a constant whose value may not be changed after creation.

const foo = "foo";
console.log(foo);   // prints "foo"

foo = "bar";
console.log(foo);   // still prints "foo"  

Private properties

With the so called „private name objects“ it is now possible to declare private object properties more simple using the “Name” module.

import Name from "@name";

let privateProperty = new Name();

function CreateObject(privateData) {
    this[privateProperty] = privateData;
    // more code
}  

At some stage it was planned to simply include the “private” keyword in ECMAScript in order to simply declare a private property by typing “private prop = “foo” but unfortunately this proposal was rejected.

Maps and Sets

ECMAScript 6 will also introduce maps and sets to the language. Maps behave like in almost any other language, allowing you to store an arbitrary amount of key-value-pairs (using the “set()” method) and to retrieve these values later on (via “get()”). Interestingly, you are allowed to use any kind of data type you want as a key.

var map = new Map();
map.set(1, 'foo');
map.set("2"), 'bar');
map.set([3, 4, 5]), 'baz');
map.set(function(){}, 42);
var map = new Map();
map.set(1, 'foo');
map.set(2, 'bar');
console.log(map.get(1) + " " + map.get(2))
// prints "foo bar"

Further map methods:

// true if the map contains the key, otherwise false
map.has(key);

// the amount of key-value pairs
map.size()

// deletes the key and its associated data
map.delete(key);  

A Set is similar to an array with the difference being that sets may only contain unique values.

var set = new Set();
set.add(1);
set.add(2);
set.add(3);
set.add(2);
set.add(1);

set.forEach(function(x){
    console.log(x);  // 1, 2, 3
};

Destructuring

This feature lets you destructure objects and assign object properties in a more expressive and concise way. Imagine we have a simple car object:

var car = {
    brand: "audi",
    color: "red",
    year: 2009
}  

Instead of assigning each property to a variable step by step, destructuring lets you do this in one simple line of code:

// without destructuring
var brand = car.brand;
var color = car.color;
var year = car.year;

// with destructuring
var {brand, color, year} = car;
  

This can also be applied to arrays:

var numbers = [7, 3, 5];

// without destructuring
var num1 = numbers[0];
var num2 = numbers[1];
var num3 = numbers[2];

// with destructuring, notice the “[]” instead of “{}”
var [num1, num2, num3] = numbers;  

Destructuring is even applicable for function arguments:

function printMyCar({brand, color, year}) {
    console.log(brand + ", " + color + ", " + year);
}

printMyCar(car);  

Default values for arguments

Besides destructuring there is another nice addition to how we can define method arguments. If you want default values for your arguments in case the caller doesn’t provide any value, you can simply declare them in your function.

function printMyCar(brand, color="blue", year=2010) {
    console.log(brand + ", " + color + ", " + year);
}

var car = {
    brand: "audi",
    color: "red",
    year: 2009
}

printMyCar(car.brand);
// prints "audi, blue, 2010"

printMyCar(car.brand, car.color);
// prints "audi, red, 2010"

printMyCar(car.brand, car.color, car.year);
// prints "audi, red, 2009"  

You can even combine default values and destructuring, resulting in something like this:

function printMyCar({brand, color="blue", year=2010}) {
    console.log(brand + ", " + color + ", " + year);
}

var car1 = {
    brand: "audi"
}

var car2 = {
    brand: "audi",
    color: "red"
}

var car3 = {
    brand: "audi",
    color: "red",
    year: 2009
}

printMyCar(car1); // prints "audi, blue, 2010"
printMyCar(car2); // prints "audi, red, 2010"
printMyCar(car3); // prints "audi, red, 2009"  

Additional features

There are even more really interesting features coming with ES6: Proxies, (custom) iterators or generator functions (like in Python) to name just a few. This resource lists all features as well as their current stage of development.

Verdict

It is to be hoped for that Ecma International really manages to finalize the specification by the end of 2013 because it seems like the new features will very well achieve the main goal to “make JS a better language for complex applications”. TypeScript, the ‘JavaScript on steroids’ by Microsoft implements many of the upcoming features of ES6 already today. Additionally it also features an optional static type checking which not only leads to safer and cleaner code but also allows for better tooling support. Real static type checking is not planned to be standardized in ECMAScript any time soon. The so called “guard” feature however could make it into ES7 and provide an alternative to static type checking.

This entry was posted in Web as a Platform and tagged , , , . Bookmark the permalink.

Leave a Reply