ES6

ES6 refers to version 6 of the ECMA Script programming language. ECMA Script is the standardized name for JavaScript, and version 6 is the next version after version 5, which was released in 2011. It is a major enhancement to the JavaScript language, and adds many more features intended to make large-scale software development easier.

ECMAScript, or ES6, was published in June 2015. It was subsequently renamed to ECMAScript 2015. Web browser support for the full language is not yet complete, though major portions are supported. Major web browsers support some features of ES6. However, it is possible to use software known as a transpiler to convert ES6 code into ES5, which is better supported on most browsers.

Let us now look at some major changes that ES6 brings to JavaScript.

Constants

Finally the concept of constants has made it to JavaScript! Constants are values that can be defined only once (per scope, scope explained below). A re-definition within the same scope triggers an error.

const JOE = 4.0
JOE= 3.5
// results in: Uncaught TypeError: Assignment to constant variable.


You can use the constant wherever you can use a variable (var).

console.log("Value is: " + joe * 2)
// prints: 8

Block-Scoped Variables and Functions

Welcome to the 21st century, JavaScript! With ES6, variables declared using let (and constants describe above) follow block scoping rules just like in Java, C++, etc. (To learn more, see how to declare variables in JavaScript.)

Before this update, variables in JavaScript were function scoped. That is, when you needed a new scope for a variable, you had to declare it within a function.

Variables retain the value till the end of the block. After the block, the value in the outer block (if any) is restored.

{
  let x = "hello";
  {
    let x = "world";
    console.log("inner block, x = " + x);
  }
  console.log("outer block, x = " + x);
}
// prints
inner block, x = world
outer block, x = hello

You can redefine constants too, within such blocks.

{
  let x = "hello";
  {
    const x = 4.0;
    console.log("inner block, x = " + x);
    try {
      x = 3.5
    } catch(err) {
      console.error("inner block: " + err);
    }
  }
  x = "world";
  console.log("outer block, x = " + x);
}
// prints
inner block, x = 4
inner block: TypeError: Assignment to constant variable.
outer block, x = world

Arrow Functions

ES6 introduces arrow functions to JavaScript. (These are similar to traditional functions, but have a simpler syntax.) In the following example, x is a function that accepts a parameter called a, and returns its increment:

var x = a => a + 1;
x(4) // returns 5


Using this syntax, you can define and pass arguments in functions with ease.

Using with a forEach():

[1, 2, 3, 4].forEach(a => console.log(a + " => " + a*a))
// prints
1 => 1
2 => 4
3 => 9
4 => 16


Define functions accepting multiple arguments by enclosing them in parentheses:

[22, 98, 3, 44, 67].sort((a, b) => a - b)
// returns
[3, 22, 44, 67, 98]


Default Function Parameters

Function parameters can now be declared with default values. In the following, x is a function with two parameters a and b. The second parameter b is given a default value of 1.

var x = (a, b = 1) => a * b
x(2)
// returns 2
x(2, 2)
// returns 4


Unlike other languages such as C++ or Python, parameters with default values may appear before those without defaults. Note that this function is defined as a block with a return value by way of illustration.

var x = (a = 2, b) => { return a * b }


However arguments are matched left to right. In the first invocation below, b has an undefined value even though a has been declared with a default value. The passed-in argument is matched with a rather than b. The function returns NaN.

x(2)
// returns NaN
x(1, 3)
// returns 3


When you explicitly pass in undefined as an argument, the default value is used if there is one.

x(undefined, 3)
// returns 6


Rest Function Parameters

When invoking a function, a need sometimes arises to be able to pass in an arbitrary number of arguments, and to process these arguments within the function. This need is handled by the rest function parameters syntax. It provides a way to capture the rest of the arguments after the defined arguments using the syntax shown below. These extra arguments are captured in an array.

var x = function(a, b, ...args) { console.log("a = " + a + ", b = " + b + ", " + args.length + " args left"); }
x(2, 3)
// prints
a = 2, b = 3, 0 args left
x(2, 3, 4, 5)
// prints
a = 2, b = 3, 2 args left

String Templating

String templating refers to interpolating variables and expressions into strings using a syntax like Perl or the shell. A string template is enclosed in back-tick characters (`). By contrast single quotes (‘) or double quotes (“) indicate normal strings. Expressions inside the template are marked out between ${ and }. Here is an example:

var name = "joe";
var x = `hello ${name}`
// returns hello joe


Of course, you can use an arbitrary expression for evaluation.

// define an arrow function
var f = a => a * 4

// set a parameter value
var v = 5

// and evaluate the function within the string template
var x = `hello ${ f(v) }`
// returns "hello 20"


This syntax for defining strings can also be used to define multi-line strings.

var x = `hello world
next line`
// returns
hello world
next line

Object Properties

ES6 brings a simplified object creation syntax. Take a look at the example below:

var x = "hello world", y = 25
var a = { x, y }
// is equivalent to the ES5:
{x: x, y: y}


Computed property names are quite nifty too. With ES5 and earlier, to set an object property with a computed name, you had to do this:

var x = "hello world", y = 25
var a = {x: x, y: y}
a["joe" + y] = 4
// a is now:
{x: "hello world", y: 25, joe25: 4}


Now you can do it all in a single defintion:

var a = {x, y, ["joe" + y]: 4}
// returns
{x: "hello world", y: 25, joe25: 4}


And of course, to define methods, you can just define it with the name:

var a = {x, y, ["joe" + y]: 4, foo(v) { return v + 4 }}
a.foo(2)
// returns 6


Formal Class Definition Syntax

Class Definition

And finally, JavaScript gets a formal class definition syntax. While it is merely syntactic Sugar over the already available protytype-based classes, it does serve to enhance code clarity. That means this does not add a new object model or anything fancy like that.

class Circle {
  constructor(radius) {
    this.radius = radius
  }
}
// use it
var c = new Circle(4)
// returns: Circle {radius: 4}


Declaring Methods

Defining a method is also quite simple. No suprises there.

class Circle {
  constructor(radius) {
    this.radius = radius
  }
  computeArea() { return Math.PI * this.radius * this.radius }
}
var c = new Circle(4)
c.computeArea()
// returns: 50.26548245743669


Getters and Setters

We now have getters and setters too, with a simple update to the syntax. Let us redefine the Circle class with an area property.

class Circle {
  constructor(radius) {
    this.radius = radius
  }
  get area() { return Math.PI * this.radius * this.radius }
}
var c = new Circle(4)
// returns: Circle {radius: 4}
c.area
// returns: 50.26548245743669


Let us now add a setter. To be able to define radius as a settable property, we should redefine the actual field to _radius or something which won’t clash with the setter. Otherwise we encounter a Stack overflow error.

Here is the redefined class:

class Circle {
  constructor(radius) {
    this._radius = radius
  }
  get area() { return Math.PI * this._radius * this._radius }
  set radius(r) { this._radius = r }
}
var c = new Circle(4)
// returns: Circle {_radius: 4}
c.area
// returns: 50.26548245743669
c.radius = 6
c.area
// returns: 113.09733552923255


All in all, this is a nice addition to object-oriented JavaScript.

Inheritance

In addition to defining classes using the class keyword, you can also use the extends keyword to inherit from super classes. Let us see how this works with an example.

class Ellipse {
  constructor(width, height) {
    this._width = width;
    this._height = height;
  }
  get area() { return Math.PI * this._width * this._height; }
  set width(w) { this._width = w; }
  set height(h) { this._height = h; }
}

class Circle extends Ellipse {
  constructor(radius) {
    super(radius, radius);
  }
  set radius(r) { super.width = r; super.height = r; }
}

// create a circle
var c = new Circle(4)
// returns: Circle {_width: 4, _height: 4}
c.radius = 2
// c is now: Circle {_width: 2, _height: 2}
c.area
// returns: 12.566370614359172
c.radius = 5
c.area
// returns: 78.53981633974483


And that was a short introduction to some of the features of JavaScript ES6.

official es6.io


src es6-features.org