For those of you that are not familiar with the name or programming language, ECMAScript is the scripting language standardized by Ecma International, widely used for client-side application development for websites and web applications, being its more popular implementation JavaScript.

ECMAScript 6 (ES6) is the upcoming version of the ECMAScript standard, with a release date in June 2015, four (4) years after the last update in June 2011. ES6 is a significant update to the language itself, since its standardization in 2009. In this post, I will discuss some of the most interesting and expected features of this latest revision.

Classes

Finally! In my opinion, this is one of the most wanted features for ECMAScript, and also one of the most criticized and obscure points of the current implementation, because JavaScript is not a conventional object-oriented language. It is actually a multi-paradigm language, which supports functional, object-oriented, and imperative programming style through the use of dynamic typing and first-class functions.

At this time, if you want to create a class, you must define it as a function.

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.moveTo = function(newX, newY) {
  this.x = newX;
  thix.y = newY;
}

var point = new Point(0, 0);

And…that’s about it: no inheritance, no interfaces, no constructors. There are ways to have these features in your code, but you can consider them hacks, and are not a part of the language specification.

Now, with ECMAScript 6, defining a class is as beautiful as:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }

  static staticMethod() {
    return 'Static method';
  }

  moveTo(newX, newY) {
    this.x = newX;
    thix.y = newY;
  }
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y);
    this.color = color;
  }

  toString() {
    return super.toString() + ' in ' + this.color;
  }
}

let cp = new ColorPoint(25, 8, 'green');
cp.toString(); // '(25, 8) in green'

console.log(cp instanceof ColorPoint); // true
console.log(cp instanceof Point); // true

Looks awesome, right? Writing a class is as simple as using the class keyword and writing it’s definition. Constructors, inheritance, and static methods are also available now.

It is important to note that these are really classes, therefore they cannot be called as functions. If you try the following in your console, you will get an error:

> Point()
> TypeError: Classes can’t be function-called

Modules

The module pattern is essential for any well architectured application. It allows you to pack your code inside dynamically loaded modules where you only expose the interface methods you want (without polluting the global namespace) and helps to define dependencies.

Currently, JavaScript does not have built-in support for modules, but the community has created impressive work-arounds. The two most important (and unfortunately incompatible) standards are CommonJS, where the main implementation is in NodeJS, and Asynchronous Module Definition (AMD), with the most popular implementation being RequireJS.

The goal for modules in ES6 was to create a format that both users of CommonJS and of AMD are happy with. It takes the best of both standards and exploits the advantage of being built into the language, allowing ES6 modules to go beyond any community implementation. Some of it’s features are:

  • A compact syntax, a preference for single exports and support for cyclic dependencies, similar to CommonJS.
  • Direct support for asynchronous loading and configurable module loading, similar to AMD.

There are two kinds of exports in ECMAScript 6: named exports and default exports.

Named exports allow you to perform several exports per module, by prefixing their declarations with the keyword export.

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
  return x * x;
}
export function diag(x, y) {
  return sqrt(square(x) + square(y));
}

//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

On the other hand, default exports let you export only one value per module, by declaring it with the keywords export default.

//------ myFunc.js ------
export default function () { ... };

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();

At this point you must be thinking that you have to chose one of these two for your library code, but actually ES6 allows you to have named exports and default exports at the same time.

//------ underscore.js ------
export default function (obj) {
  ...
};
export function each(obj, iterator, context) {
  ...
}
export { each as forEach };

//------ main.js ------
import _, { each } from 'underscore';

It is helpful for making sense of ECMAScript 6 modules, understanding before what goals influenced their design. The major ones are:

  • Default exports are favored
  • Static module structure
  • Support for both synchronous and asynchronous loading
  • Support for cyclic dependencies between modules

Bottom line With the upcoming version of ECMAScript there are a lot of new and extremely wanted features for us JavaScript developers. Some other features left for future post are: arrows, enhanced object literals (!), template strings, let + const, iterators + for..of, generators and promises. Fortunately for us, the implementation of these awesome features in major JavaScript engines is underway now: https://kangax.github.io/compat-table/es6/

Examples and references in this post have been taken from http://www.2ality.com and https://github.com/lukehoban/es6features.