ES6 or ECMAScript 2015 or JavaScript 6 has been released since 2015 although it still has no full support by some of the major engines. This has been a major update and the only one since it was standardized by 2009. There are a few new things, although nothing really groundbreaking. Most of the new stuff is just to avoid boilerplate code and some syntax sugar. Ok, this may not be a complete breakthrough for JavaScript but it will make our coding simpler and easier. Here you are a list of the new features included:

CONSTANTS

We could create constants before (immutable variables) but we had to type some boilerplate code that we don’t like. A constant makes the variable itself immutable but still the content may change if for example the content is an object, the object can change although the variable itself cannot. This was the code we had to type before in order to make a “constant”:

// only in ES5 through the help of object properties // and only in global context and not in a block scope Object.defineProperty(typeof global === "object" ? global : window, "PI", { value: 3.141593, enumerable: true, writable: false, configurable: false }) PI > 3.0;

With the new syntax we can define a variable directly as a constant and avoid to type all the boilerplate code:

const PI = 3.141593 PI > 3.0

ARROWS

This is something many people are going to love, especially those coming from other languages using arrows like C#. This may not change anything, or almost nothing to the language but it is still one of the favorite new functions. First of all it provides lexical scoping of the this word. When you code in JavaScript you are used to use the “this” word for every function. With the arrow function you will stop using the “this” word as much as you did. Take a look at the following snippets:

// variant 1 var self = this; this.nums.forEach(function (v) { if (v % 5 === 0) self.fives.push(v); }); // variant 2 (since ECMAScript 5.1 only) this.nums.forEach(function (v) { if (v % 5 === 0) this.fives.push(v); }.bind(this));

The above is an example of how much times we have to use the “this” word and how much we hated to do it. Now with the new ES6 we can just do the same like in the following one:

this.nums.forEach((v) => { if (v % 5 === 0) this.fives.push(v) })

Much cleaner, not so much boilerplate code and simpler to use. We all love the arrows in CoffeeScript and this is something similar. Not the same, but similar. They can also be used in statement block bodies and expression bodies as in the following examples:

odds = evens.map(function (v) { return v + 1; }); pairs = evens.map(function (v) { return { even: v, odd: v + 1 }; }); nums = evens.map(function (v, i) { return v + i; });

Now with the arrow function we no longer need so much ceremony for expression bodies and we avoid to create functions for the purpose:

odds = evens.map(v => v + 1) pairs = evens.map(v => ({ even: v, odd: v + 1 })) nums = evens.map((v, i) => v + i)

CLASSES

OOP or Object Oriented Programming is just a matter of tastes but the fact was that OOP in JavaScript was quite a painful thing because we didn’t have classes. We actually could create classes by typing a lot of boilerplate or, better said, we could emulate the classes of other programming language with a lot of boilerplate code. There was no class keyword (it was reserved though, but nobody knew what it was useful for).

There were many ways to write a class in JavaScript or at least how to emulate one, but now we no longer will need these techniques to do it, because we have real and authentic classes. For example, this was one way to define a class before:

var Shape = function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; };

And now with our all-new class keyword:

class Shape { constructor (id, x, y) { this.id = id this.move(x, y) } move (x, y) { this.x = x this.y = y } }

Ok, this may not look like saving a lot of boilerplate code, but the benefits are much more with class inheritance. Before the ceremony to implement class inheritance was huge and a pain in the rear for coders. Now inheritance is implemented in a more intuitive way and OOP style. For example, in the code below, we do some inheritance in ES5:

var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); this.width = width; this.height = height; }; Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var Circle = function (id, x, y, radius) { Shape.call(this, id, x, y); this.radius = radius; }; Circle.prototype = Object.create(Shape.prototype); Circle.prototype.constructor = Circle;

This is quite ugly and difficult to read, not to mention painful to type. The new way will look like this:

class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y) this.width = width this.height = height } } class Circle extends Shape { constructor (id, x, y, radius) { super(id, x, y) this.radius = radius } }

As we mentioned before, it is nothing groundbreaking, it is a feature we have in many other languages but now we also have them in JavaScript. This will make the language more object oriented for those who like OOP.

DEFAULT PARAMETER HANDLING

This is quite a sugar coat for the language. Now in our function parameters we will have an enhanced parameter handling and it will be much easier to define default values. In the old style we had to do this:

function f (x, y, z) { if (y === undefined) y = 7; if (z === undefined) z = 42; return x + y + z; }; f(1) === 50;

And now we will have a more intuitive way to do the same and without having to type so much if, if, if:

function f (x, y = 7, z = 42) { return x + y + z } f(1) === 50

Quite nice and simple and free of the boilerplate code we all hate so much.

TEMPLATE LITERALS

Template literals is the fancy JavaScript way to say interpolation and basically it is a way to output variables in the string. This works not only for single line but also for multi-line strings. Before we had to do this to do it:

var customer = { name: "Foo" }; var card = { amount: 7, product: "Bar", unitprice: 42 }; var message = "Hello " + customer.name + ",

" + "want to buy " + card.amount + " " + card.product + " for

" + "a total of " + (card.amount * card.unitprice) + " bucks?"; And now we have the ${NAME} so we can do this instead: var customer = { name: "Foo" } var card = { amount: 7, product: "Bar", unitprice: 42 } var message = `Hello ${customer.name}, want to buy ${card.amount} ${card.product} for a total of ${card.amount * card.unitprice} bucks?`

We no longer need to open and close “” for each string and we also no longer need to add with + and + and a whole lot of + symbols. This is just syntactic sugar but we all love syntax as sweet as possible.

DESTRUCTURING

Destructuring may be a difficult concept to get but it is quite useful and now we have an easier way in ES6. Object matching, parameter context matching and array matching can be done now in a more intuitive and flexible way and again, with sugarcoated syntax. To put some examples in ES5 we had to do this:

var tmp = getASTNode(); var op = tmp.op; var lhs = tmp.lhs; var rhs = tmp.rhs;

While now we can just do it in a single line of code and without all the boilerplate:

var { op, lhs, rhs } = getASTNode()

It also works with arrays as in the following example:

var list = [ 1, 2, 3 ] var [ a, , b ] = list [ b, a ] = [ a, b ]

Yet again, more sugarcoat for our syntax.

MODULES

Even though we all used tons of modules in ES5, there was no native modules support for then before the arrival of ES6. We will not mention all the workarounds we used to load modules but now we have the import and export keywords to do the same we have been doing before. Modularity in large applications is so important that it only made sense for ES6 to include it in a language level feature. An example of exporting and importing values without so much pollution:

lib/math.js

export function sum (x, y) { return x + y } export var pi = 3.141593

someApp.js

import * as math from "lib/math" console.log("2π = " + math.sum(math.pi, math.pi))

otherApp.js

import { sum, pi } from "lib/math" console.log("2π = " + sum(pi, pi))

While this is cool, it brings up some problems for full stack developers or actually, for stacks. Seems NodeJS is not going to change the modules policy soon, or ever. So it is always better to use the same style for the browser and the server. Also, browsers don’t seem to support ES6 modules so if you want to use this new way you will have to use jspm. Modular JavaScript is the way to go but seems we will not be using this feature anytime soon.

BLOCK SCOPING

If you come from a Java or C# background you have already noticed how confusing scoping in JavaScript is because variables are either global or locally function scoped. There were some patterns to achieve block scope like hoisting but now we can use the “let” keyword to achieve block scoping without hoisting. For example in the below example you can see block scoping achieved through hoisting:

var i, x, y; for (i = 0; i < a.length; i++) { x = a[i]; … } for (i = 0; i < b.length; i++) { y = b[i]; … } var callbacks = []; for (var i = 0; i <= 2; i++) { (function (i) { callbacks[i] = function() { return i * 2; }; })(i); } callbacks[0]() === 0; callbacks[1]() === 2; callbacks[2]() === 4;

While now we can use the let keyword to do the same and achieve block scoping in a more intuitive way for those coming from other languages:

for (let i = 0; i < a.length; i++) { let x = a[i] … } for (let i = 0; i < b.length; i++) { let y = b[i] … } let callbacks = [] for (let i = 0; i <= 2; i++) { callbacks[i] = function () { return i * 2 } } callbacks[0]() === 0 callbacks[1]() === 2 callbacks[2]() === 4

PROMISES

We all have used promises before via many different libraries like q, vow, avow, jquery, deferred.js… and there were many different syntaxes to do the same thing. Also, without the aid of any libraries we could do the same we do in a promise with generators or callbacks to name a few methods but now we have the promise implemented and we can do it in a standardized way.

function msgAfterTimeout (msg, who, timeout) { return new Promise((resolve, reject) => { setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout) }) } msgAfterTimeout("", "Foo", 100).then((msg) => msgAfterTimeout(msg, "Bar", 200) ).then((msg) => { console.log(`done after 300ms:${msg}`) })

Basically, this way will only have benefits when there is a huge nested logic and still, the benefits are scarce. Once we have all been used to use callbacks, this only adds more complexity however, if you like promises and you have used them before, now you have a standard way to do it.

MORE FEATURES

There are many more features which we will not go deep into because they are quite simple like the new built-in methods that allow us object property assignment, array element finding, string repeating, string searching, number type checking, number safety checking, number comparison, number truncation and number sign determination. There are also additions for internationalization and localization as number formatting, currency formatting and date and time formatting. It now also supports “iterable” protocol for objects in order to customize their behavior in the iteration and generators which are basically a special case of iterators.

CONCLUSION

While it is a nice update to the very old ES5, it doesn’t really bring anything groundbreaking or really new. Mostly all, if not completely all that can be done with ES6 could be done with ES5, even more when we consider we have really good tools for it like TypeScript to name one. Also, it is far from being well supported by many browsers and if you use it today you are likely to be in a world of trouble. You can use a compiler like Babel to compile your code from ES6 to ES5 so that it is fully supported but still, until there is a full support from browsers, the new ES6 won’t be widely spread.