The team/committee (known as TC39) who is responsible for developing new features for ECMAScript is coming with a new set every year. This started on 2015, hence the name ECMAScript2015, which is also known as ES6. ES6 comes with a lot of new features, and most are pretty helpful. However, the naming convention of the ECMAScript is confusing. Therefore, let's clear some acronyms first.

What is ECMAScript?

To start with, JavaScript is not ECMAScript.

ECMAScript is the language specifications that JavaScript is based on which is also known as ES for short, while JavaScript is the implementation of the ES.

JavaScript is not the only implementation out there. For instance, JScript is another implementation that was developed by Microsoft to be used in Internet Explorer. JavaScript, JScript and other implementations of ECMAScript are known as "dialects", and JavaScript is the most popular one of them.

Now ECMAScript2015, ES2015, and ES6 all represent the same thing which is a representation of a certain version of the specifications or the standard (ECMAScript). The styling of the specs version was like ES5, ES3 and so on. However, what is confusing is that they decided to change this styling convention to be like ES2015 instead of ES6. And so forth, ES7 will be ES2016, ES8 will be ES2017...etc.

A couple of more things that one could find on the subject are "ES Harmony" and "ES.Next". ES Harmony represents a list of all the features that the TC39 interested in or working on, and might come in the next version of ES. One can think of it as a to-do list of features. ES.Next is used as an alias to the next version of ECMAScript, which according to this date is ES2018.

The roadmap of ECMAScript could be found here.

JavaScript Transpilers

The specs of ES6 were released before they were fully available to let the browsers adapt as fast as possible. However, to overcome the absence of the features in the browsers, what was known as transpilers was born.

Transpilers were able to transform ES6 syntax to the plain old ES5 syntax that would be compatible with the browsers. The most popular transpiler by that time (and still) was "6to5" which has been renamed to Babel.

Browsers And Node.js Support

ES6 features are almost entirely supported in the current versions of all the major browsers; Chrome, FireFox, Opera and Edge. Beyond that to the server-side JavaScript; in Node.js, the features that are implemented by Chrome's V8 are supported by Node.js.

Why Using ES2015?

First and foremost, because it is a standard. It makes the developer's life easier by providing those syntactic sugar bits. It also helps in structuring the application by providing native support for modules. Some might argue about the browser support, but for that, there are always transpilers. So let's dig into the ES6/ES2015 features.

Block-Scoped Variables (let)

The var's scoping behavior in JavaScript is hideous. It declares a variable, and the scope of that variable is its current execution context, which is either the enclosing function or, for variables declared outside any function, global. However, the scoped if or for statement doesn't affect the declared variable. Let's explain this in an example.

var name = 'Jack';

if (true) {
    var name = 'John';
}

console.log('The name is:', name);

The outcome is The name is: John. That's because of the second variable name within the scope of the if statement replace the first variable name in the global scope. That's due to how JavaScript hoisting works, which could cause a lot of bugs if one is not aware of this behavior.

let would solve this problem by allowing us to declare block-scoped local variables. Let's see this in the same example.

var name = 'Jack';

if (true) {
    let name = 'John';
}

console.log('The name is:', name);

The outcome is The name is: Jack, which is exactly what we would expect.

Also, at the top level of programs and functions, let, unlike var, does not create a property on the global object.

var var1 = 'global';
let var2 = 'global';
console.log(this.var1); // "global"
console.log(this.var2); // undefined

let is also used to emulate private members. Let's see the following example from MDN.

var SomeConstructor;

{
    let privateScope = {};

    SomeConstructor = function SomeConstructor() {
        this.someProperty = 'foo';
        privateScope.hiddenProperty = 'bar';
    }

    SomeConstructor.prototype.showPublic = function() {
        console.log(this.someProperty); // foo
    }

    SomeConstructor.prototype.showPrivate = function() {
        console.log(privateScope.hiddenProperty); // bar
    }

}

var myInstance = new SomeConstructor();

myInstance.showPublic();
myInstance.showPrivate();

console.log(privateScope.hiddenProperty); // error

This technique only provides "static" private state - in the above example, all instances of SomeConstructor will share the same privateScope.

The browser support for let could be shown here.

Constants (const)

In ES5, developers used to define constants by declaring a variable using var and as a convention that variable was all uppercase letters.

var API = 'http://api.example.com/';
var API_VERSION = 'v1';

console.log(API_VERSION); // v1

API_VERSION = 'v2';

console.log(API_VERSION); // v2

This didn't actually prevent the variable from being re-assigned, but it was showing the intention of the author that those are meant as constants. ES6 introduces const keyword which allows us to declare block-scoped variables much like the variables that are declared using let. The difference is that the value of a constant can not change through re-assignment, and it can't be redeclared.

Let's take the same example from above and declare API and API_VERSION as constants.

const API = 'http://api.example.com/';
const API_VERSION = 'v1';

console.log(API_VERSION); // v1

API_VERSION = 'v2';

console.log(API_VERSION); // Uncaught TypeError: Assignment to constant variable.

An error has been thrown with a message Assignment to constant variable.

Some use cases of using this feature are when defining the endpoint call for the back-end's API as shown in the previous example, and in Node.js, specifying a port number is a common use case for using const.

The browser support for const could be shown here.