Quick Links

JavaScript powers most of the interactive web, and so it's had to evolve alongside it. New features in JavaScript are being added every year now; we'll take a look at what's new, and how you use ES6 JavaScript on your website.

JavaScript Has Many Flavors

Oracle has a trademark on the term JavaScript, so the actual standard that modern JavaScript implements is called the ECMAScript standard, or ES. The primary JavaScript standard is ECMAScript 5, or ES5, released in 2009. This is vanilla JavaScript without any special features, supported everywhere, even in IE 9.

ES6 is a fairly new specification, released in 2015, and supports many new features. It's technically called ES2015, and each annual release after it is denoted by the year of its release. But everyone calls it ES6 anyway, so we're sticking with that.

ES6 is important, in particular, as it marks the start of JavaScript's restandardization. Nowadays, ECMA releases a new standard annually. But ES6 was released 6 years after ES5, which was 10 years after ES3, so it's a major milestone.

How to Use ES6 Syntax

ES6 is actually supported in a lot of places, with the main problem being Internet Explorer (as usual). So, while you may be able to just start writing with ES6 style, you can't be certain everyone's browser will behave the same.

Nowadays, it's still usually compiled down to "regular" ES5 syntax with the help of a utility like Babel. Babel is a compiler that will convert your development code (written in ES6 with all of its goodies) to code that you will run on your production site, often bundled and minified with Webpack as well.

Here's how it works: you have your development environment where you write your

        .js
    

 files. You're free to use whatever fancy ES6 syntax you like. Rather than running them directly, you set up Webpack to load JS files with Babel. Often, you'll want to run webpack-dev-server, so this happens automatically when you make changes.

Now instead of loading

        index.js
    

, you load

        bundle.js
    

, which contains all of your code. This also has the great benefit of allowing you to use NPM modules in your JS, though it can make your code bulky if you add too many (though webpack is pretty great at minification).

What's New

There's a lot to unpack here, so this article certainly won't cover everything. For a full list, you can view this compatibility table, which also includes ES2016 and newer features.

In general, if Babel can compile something to an older specification of JS, it's probably safe to use in development. If it doesn't, and you don't care about the 3% of the population using IE 11, it's probably supported in most browsers provided it's not a super new feature.

Arrow Functions

Rather than typing:

arr.map(function (d) {
    

return d + 1;

});

You can instead replace the function keyword with an arrow after the parentheses:

arr.map((d) => {
    

return d + 1;

});

Additionally, you don't need the parentheses if you only pass one argument. And, you don't need the brackets and return statement if you're only returning one value:

arr.map(d => d + 1);

This is the new expression closures syntax, and makes for nicely compacted functions, especially when working with lists, callbacks, or error handling. It's similar to how single line if statements work.

Simplified Object and Array Creation With Destructuring

Rather than writing:

var type = "123", color = "blue"
    

var obj = { type: type, color: color }

You can simply omit the key names, and they will be automatically set to the variable names:

var obj = { type, color }

Additionally, this works the other way around, called destructuring assignment:

var { type, color } = obj

A fancy side effect of destructuring is the ... syntax, which acts like "etc." and assigns the rest of the array or object to a variable:

var { type, ...rest } = obj
    

//rest == { color: "blue" }

And, it also works the other way around, which has the effect of expanding and flattening arrays:

var arr1 = ["a", "b"], arr2 = ["c", "d"]
    

var flat = [...a, ...b, "e"]

//flat = ["a", "b", "c", "d", "e"]

There's way more to destructuring than is covered here.

Classes

JavaScript has classes now. Here's how it works, from Mozilla's docs:

class Rectangle {
    

constructor(height, width) {

this.height = height;

this.width = width;

}

// Getter

get area() {

return this.calcArea();

}

// Method

calcArea() {

return this.height * this.width;

}

}

const square = new Rectangle(10, 10);

console.log(square.area); // 100

As you can see, it's similar to other object-oriented languages, but not quite. As Mozilla states, this new system is "primarily syntactical sugar over JavaScript's existing prototype-based inheritance" and does not actually make JS object oriented. But, it's still nice to have.

Additionally, the class syntax supports static methods and properties, and child classes, but a child class cannot inherit from multiple parents.

Changes To Function Arguments

ES6 introduces two new ways to write function parameters. First, default parameters can be specified by assigning a value in the function definition:

var func = (a, b = "default") => { }

If you were to call func without specifying two arguments, it would assume the default value.

Also, functions can now be given an indefinite number of arguments as an array, called the rest function parameters syntax:

var func = (a, b, c, ...rest) => { }

The rest parameter will be set to an array of the rest of the function parameters, or undefined if no more than the named parameters are present.

let and const

The let command is a replacement for var that specifically grants block scope. Here's how variables work in JS normally:

var x = 0; //global variable
    

function someFunc() {

var y = 3; //local variable

}

The global variable can be used in the function, but the local function variable cannot be used outside of the function. This is what allows you to name your variables "i", "tmp", "x", and "count" all the time and get away with it.

Block scope is different, and allows you to redefine variables with nested blocks:

var x = 0
    

{

let x = 2

//x == 2

}

// x == 0 again

The let syntax essentially lets you modify the contents of x within that block (be it a function, catch block, or an explicit block like so), and have it reset when leaving the block. This is particularly useful for those temporary "count" variables, as each block will have a different scope. The scope is inherited to child blocks, but can be further nested and changed again.

The const syntax is fairly straightforward. Replace var with const, and your variable is now read-only. If you try to write to it, it will throw:

Uncaught TypeError: Assignment to constant variable.

Letting you know you're trying to do something you shouldn't. This has no purpose other than being a nice reminder when coding to prevent some bugs.