A quick dive into ECMAScript 6 – the Future of JavaScript

The web is a confusing and beautiful mess, and a central part of that is its scripting language, JavaScript. It is the only programming language that is native to the web, and can run directly in any browser.

What this means is that the capabilities of the web are closely tied to the capabilities of JavaScript and likewise the productivity of working on web apps is tied to how productive JavaScript is. With the push for HTML5, JavaScript now has a larger surface area of features to work with. It can work with 3D objects using WebGL, it has a rich 2D API using the HTML5 canvas. There is video, audio, WebRTC for real time communication, and a whole lot more.

However, there are many convenient features that are still missing from JavaScript that developers have been clamouring for. This is where the latest ECMAScript 6 standard comes in. If you’re wondering where ECMAScript comes in when we are talking about JavaScript, let’s take a quick look at the history of the language to understand this mess.

A Brief History

JavaScript has been around for a long time, this is in fact the 20th year of its existence. Back when it was conceived, it was no different that something like Flash or Silverlight, i.e. a proprietary solution offered by a single vendor to differentiate their product. It showed up in Netscape Navigator 2.0 and drove Microsoft to create its own scripting language JScript that was compatible with JavaScript.

To make sure that the web didn’t end up with a dozen splintered, and slightly different dialects of the same scripting language, JavaScript was soon standardised by Ecma International (European Computer Manufacturers Association) a standards organisation. This standard is what is known as ECMAScript. JavaScript is thus an implementation of the ECMAScript standard. The specification for all revisions of ECMASCript can be downloaded from the Ecma website: http://www.ecma-international.org/

The ECMAScript standard went through many revisions, notably ECMAScript 3 was the first somewhat major update to the language. ECMAScript 4 was supposed to be an even more ambitious update to the language with the addition of a type system, modules, classes and a lot more. ECMAScript 4 was abandoned and the language moved to a different direction with ECMAScript 5. If

The Lost ECMAScript 4

If you’re wondering what ECMAScript 4, check out ActionScript 3.0, the programming language used by the Flash Player. It was based on ECMAScript 4, and is now the closest you can get to what this edition of JavaScript would have looked like had it been accepted.

Now JavaScript seems to have embraced a quicker pace of development. Even as ECMAScript 6 is being implemented in currentgeneration browsers, ECMAScript 7 is already being designed. In fact ECMAScript 6 is also known as ECMAScript 2015 or ES2015 and ECMASCript 7 is called ECMAScript 2016. Rather than repeat the rather verbose and clumsy ECMAScript 6 or ECMAScript 2015 we’ll use the shorthand ES6 for the rest of the article.>

you currently code for the web, this is the version of the language that is widely supported and available in browsers.

What’s New With ES6

There is a whole lot new in ECMAScript that we just can’t get into in the scope of a single article, and quite a few of the improvements have to do with subtleties of the language that would take up an entire chapter of a book to explain. We will only look at the more major and high-impact features.

That said, let’s quickly dismiss some of the small (but no less significant) features.

• const: It may surprise you to know how difficult it has been to declare a constant value till now. With ES6 it is now as simple as typing const ABC = ‘xyz’.

• let: This might be a simple addition to JavaScript, but its significance is more complex to expound. Variables defined as let var = ‘value’ only exist within the block in which they are defined, unlike variables declared with var.

• Proxies: Using proxy objects, you can intercept calls to another object or function and use the opportunity to modify it’s characteristics or perhaps log the interactions with that object. It has some great implications that are out of scope for this article.

• Tail-call optimisation: While recursive algorithms for common problems such as calculating factorials are fun to learn and code they are often impractical. Each time a function calls itself, the computer needs to keep track of the entire chain of function calls.

This makes recursive programs impractical except in very simple cases. With Tail-call optimisation properly coded recursive functions can work even with millions of levels of recursion. Such functions pass on computation to the next recursive call leaving nothing for the calling function to do. So the computer need only keep track of the latest recursive call.

Improvements to Functions

The first improvement to functions is the addition of the new shorthand => for declaring functions. With this new syntax, you can create functions as:

(num1, num2) => num1 + num2
This is equivalent to:
function(num1, num2) {
return num1 + num2;
}

If you find this new syntax a little pointless, thing of the kinds of situations where you need to have a one-off function. For instance, if you want to filter an array keeping only the even numbers, here is how you would need to do it with the current JavaScript syntax:

array.filter(function(e) {return e % 2 == 0; });
Compare this to the equivalent code in ES6:
array.filter(e => e % 2 == 0);

Hopefully you’ll agree it’s a lot cleaner. You don’t need to limit yourself to single-line functions with this new syntax either, you can use a code-block to extend such functions to multiple lines. For example:

(num1, num2) => {
if (num1 < num2) {
return 1;
} else {
return 2;
}
}

Another great addition to ES6 is the ability to define functions with default values for parameters. In current-generation JavaScript, you need to check if a parameter value is undefined and in that case assign it the default value. With ES6, this is simply part
of the languages:

function add(num1=1, num2=2) {
return num1 + num2; // returns 3 if no arguments are supplied
}

Finally we have support for arbitrary length arguments using the new spread operator …. In a function defined as function add(… nums) the variable nums will be an array containing all the arguments provided to that function. So you could call this function
as add(1,2,3,4,5,6) and the variable nums would then be the array [1,2,3,4,5,6]. The function can have additional arguments before such an argument as well.

Destructuring

Desrtucturing is a powerful feature that allows you get data from inside data structures a lot more naturally. For instance if we have the following array:
let arr = [1, {x: 11, y: 12}, 17];
As you can see this array contains three elements, the first and third are numbers, and the second is an object. If we wanted to retrieve the x and y values from the second element of this array, it isn’t difficult, but with destructuring it is a lot clearer:
let [, {x: x1, y: y1}, ] = arr;
The above code will result in x1 being equal to 11 and y1 equalling 12. This can be particularly useful if you are dealing with a function that returns a structure, and you just want some data inside the structure. For instance:
let {x: x1, y: y1} = coordinatesOf(someShape);
Likewise this destructuring can be a part of function parameters as well: function coordinatesOf({width: width, height: height, size: size}) {…}
This above function will allow you to pass parameters as a structure, but you don’t need to write the code to extract data inside that object, it will be directly available via the variables height, width and size.

Modules

This is probably one of the biggest additions to JavaScript with ES6, since it stands to change the way that applications and libraries are structured and written.

The new module syntax allows developers to include code from external JavaScript files in a manner similar to other programming languages like Ruby, Python etc.

This would allow you to write future jQuerydependent code as:

import $ from “libs/jquery”;
$(‘.element’).hide();
If you wanted to write your own bit of JavaScript
code that can be imported in other files you
could do:
export default function (a,b) {
// does something
}

You can also export named variables as export var sheep_count = 11;. Likewise you can
import such variables import sheep_count from “sheeplib”;.

On the server side, the Node community has already had to come up with its own system for loading external modules using the CommonJS module format, which has its own browser equivalent:

RequireJS. A number of other systems for modularising JavaScript have arisen over the past few years, but with ES6 there will finally be an official, native way built into the browser.

Classes

JavaScript uses a rather uncommon approach to Object Oriented programming, that uses prototypes, rather than classes. Even so, class-based object-oriented programming is still the most dominant paradigm, and with ES6, JavaScript is embracing that.

While ES6 classes wukll continue to use prototypes under the hood, developers can now use a syntax that they are more familiar with:

class AwesomeButton extends SimpleButton
{
constructor(width, height) {
super(width, height);
this.width = width;
this.height = height;
}
get dimensions() {
return {width:this.width, height:this.height};
}
// …
}

String Interpolation and Templating With ES6 there is a new way to declare strings that adds a number of convenient features for those dealing with long multi-line strings and those wanting to cleanly insert variable values inside strings (string interpolation). Using backticks (`)` you can easily create multi-line strings by simply typing the string across multiple lines. For example:

let htmldoc = `<html>
<head><title>Some Title</title></
head>
<body>
</body>
</html>`;

The above HTML code sting will be interpreted literally, i.e. line-breaks will translate to \n characters in the htmldoc string.

Using string interpolation we can also easily inject variables inside strings a lot more easily,
for example: let message = `Are you sure you want to remove ${book} by ${author}?`;
Here the value of the book variable and the author variable will automatically be inserted
in string at their placeholders. The bit inside the ${} doesn’t need to be a variable, it can be any
JavaScript expression. For example: let message = `The time is:
${formatTime(getTime().toTimezone(‘IST’))}`;

In the above example, the value inserted will be the result of evaluating the contents inside
the ${}.

Promises

Promises offer a much cleaner alternative to asynchronous programming than callbacks. If you are not familiar with these terms, here is a brief. When you perform a task that will take time (for instance downloading an image), there are many ways to handle the wait. Either the entire application can halt while that task is being completed, or the application can continue responding and deal with the result of that task later.

The callback approach is that when you launch a task in the background that will take time, you also provide it with a function, called a callback function that will be sent the result of the task when it is complete. This can get convoluted quickly if you have multiple dependent tasks.

For instance you want to do task1 which complete should launch task2 which should launch task3. With each callback the code becomes more confusing as you have callbacks within callbacks within callbacks. For example:

downloadImage(“image1”, function(img1) {
downloadImage(“image2”, function(img2) {
downloadImage(“image3”, function(img3)) {
//…
});
});
});

Promises are a differnt approach to the same problem. With promises the above will look like:
Download Image(“image1”)

.then(() => downloadImage(“image2”))
.then(() => downloadImage(“image3”)) //…

We won’t got into how you can use promises in your code since it’s out of scope, however if you often write asynchronous code, they are definitely worth checking out.

Generators

Imagine a function that keeps running even after it has returned a value. In fact it can keep returning values as long as needed. On the other hand, you can call such a function, and what you get is an object that can keep returning the next value when you ask for it.

This is a concept that is popular in Python, and is now part of ES6. Let’s look at a simple generator that returns

consecutive odd numbers starting with 1:
function* oddNumbers() {
let num = 1;
while(true) {
yield num;
num += 2;
}
}

You’ll notice two odd things about the above function. The first is that there is * following function. This is not a misprint, it is the syntax to define a generator function. The second oddity is the presence of the yield keyword instead of the usual return. Where return returns a
value and ends the execution of the function that returned the value, yield continues executing even after the value has been generated. Ihe the above case you could use the generator as follows:

let oddNums = oddNumbers();
oddNums.next(); // returns {value: 1, done: false}
oddNums.next(); // returns {value: 3, done: false}
oddNums.next(); // returns {value: 5, done: false}

It is also possible to create an iterator using a generator which would allow you to use it in expressions such as for(num of odd- Numbers) {…}.

How to Use ES6 Today

We wouldn’t tease you with the good stuff that is coming with future versions of JavaScript if there wasn’t a way to start using it already. While a lot of these features are still not fully supported across the browser spectrum, most engines have already implemented over half of these features. Microsoft is for once leading the charge in implementing these new features and if you are looking to play with these new features you should check them out on their new Edge browser.

babel

You can find out how to configure Babel for your workflow at babeljs.io

nodc

With the release of Node 4.0 a lot of ES6 features such as proxies, promises, arrow functions etc. are available in Node.

Fact is though, you will need to support old JavaScript for a long time, even if all browsers reach 100% support for ES6 over the next few months. It obviously makes little sense to code everything twice, once in ES6 and once in ES5, that would defeat the point of the improvements in ES6.

If you want to start using ES6 already but want to still support older browsers, you should check out a project called Babel that compiles ES6 JavaScript to ES5 JavaScript, allowing you to take advantage of the new syntax today while still targeting older browser users. Once you feel ES6 has achieved the level of mass acceptance you want, you can simply use the ES6 code directly instead of passing it through Babel.

Leave a Comment

Your email address will not be published. Required fields are marked *