JavaScript Error Handling

ES6 JavaScript: Whats New? – Part 1

The latest and greatest active version of JavaScript is ES6 (aka ECMAScript 6, aka ECMAScript 2015). Most modern browsers now support the majority of the new features and capabilities offered with ES6, so we thought we’d try to show you just what cool new stuff you can do with the latest version of JavaScript. There are many new features added to ES6, so we’ll just cover a handful in this article, and try to touch on the remainders in future pieces, so let’s get to it!

A Quick Note on Naming Conventions

For better or worse (most developers would argue for worse), JavaScript version naming has been a somewhat confusing mess lately. JavaScript is generally standardized using the ECMAScript language specification, which has been through roughly seven major versions since its creation in 1997. However, version naming have been rather complicated by mixing between numeric iterations (e.g. ECMAScript 6 / ES6) and year-based iterations (e.g. ECMAScript 2015). ES6, which was standardized in 2015, is often referred to by either the numeric or year-based version, which can often cause confusion. However, the real issue with a year-based system is that the upcoming version, ES7 or ECMAScript 2016, has not been standardized yet, well into 2017.

The consensus is likely to land on sticking with numeric naming moving forward, so hopefully ES6 will move to ES7, and so forth down the line.

Default Parameters

ES6 introduces a much-beloved feature of many other languages: the ability to define the default values for parameters within your functions or methods. Making use of this feature is rather simple; just include an equals sign after the parameter name, followed by the default value. For example, here our last parameter for the getFullNamefunction includes a default value of "the Unknown":

This makes it simple to provide values only for the parameters that are required, allowing the default to be inserted where necessary:

This produces the output of "Alice the Unknown" when no last argument is given:

Classes

ES6 also introduces the class ability to create traditional classes, similar to many other object-oriented languages. While behind-the-scenes JavaScript is effectively treating classes in ES6 as prototypes, classes provide a clean new syntax and something that will be familiar to many people coming to ES6 from other object-oriented languages.

The introduction of classes brings a lot of new syntax and possibilities, so we’ll just start with a simple example, then discuss what’s new:

The obvious new addition is defining our Book class with: class Book {}. We’re also using a constructor()method, which defines how we initialize our class when the time comes, providing a number of properties for our constructor() parameters.

We’ve also included a prototype method (often known as a class method in other languages) which is a method attached to an instance of that class (as opposed to a static method, which cannot be accessed by an instance of that class object). In this case, we’re creating the wordsPerPage() prototype method.

Since we’re also using the get keyword, which informs JavaScript that this is a getter, wordsPerPage isn’t technically a method, but, instead, is a property. This means we call it without closing parentheses or passed in arguments: book.wordsPerPage.

We’ve next created a second class called PaperbackBook, which inherits from our Book class using the extendskeyword:

Notice in our constructor() we’re also using ...args as our list of arguments, which are known as rest parameters. Rest parameters simply represent an indefinite number of arguments, in the form of an array. Therefore, when we create a new instance of PaperbackBook, since it extends Book, the ...args argument will contain an array of all four actual arguments passed into it, which is what Book expects.

From there, we then make use of the super keyword, which allows us to reference the parent of our PaperbackBookobject. Thus, combining super with ...args, we can simply call super(...args) in our constructor, which will effectively call the constructor of the parent Book class, and pass all provided arguments along with it. This makes it easy for us to extend the functionality of PaperbackBook's constructor, in this case simply by adding the coverType property.

With our classes defined, we create a new instance of each class, passing in values that represent two different books, then output the information to our console to ensure everything works as expected:

The output:

Sure enough, we’re able to output the particular class objects we created, along with the wordsPerPage property value that is a getter, and then also confirm that coverType is only defined for our PaperbackBook class instance, but not the Book class.

Lastly, we’re also using the new static keyword to define a static method inside our Book class. In fact, you may notice we’re using the same name of wordsPerPage, so that we can use our Book class to make calls to static methods, without the need for a reference to a particular instance of the class. In this case, if we want to calculate the words per page from two numbers, without using a Book class instance, we can do so:

Using our static method of wordsPerPage here works just as expected:

Block-Scoping and the let Keyword

Properly scoping localized variables has always been a bit frustrating, or at least abnormal, in JavaScript. In most languages, including JavaScript, it is often necessary to create a block scope, which is basically a section of code that is separated and retains privacy from code outside of that block. In ES5 the common technique to create a block scope is to use an immediately invoked function expression (IIFE). This is effectively a syntactic method of defining a function, which is itself surrounded by parentheses, which effectively tells the JavaScript engine that this function should be treated as a grouped entity.

For example, here’s how we’d use an IIFE in ES5 as a way to create a block scope, allowing us to privatize the different value assignments of our name variable:

The result is that our first console.log() output is Bob, while our second, which is outside of the block scope of our IIFE, is Alice:

Without the IIFE here, we could try creating a block scope with a pair of braces ({}), like so:

The problem is, our braces don’t properly retain the private scope of our name assignment to Bob since we’re using the var keyword. Therefore, our output is Bob both times:

The proper way to do this in ES6 is to continue using the braces to define a block scope, but to use the letkeyword instead of var inside our block scope:

The let keyword is an easy way to create a block scope local variable in ES6. Thus, our name is properly retained inside our block, as well as outside:

To help you and your team with JavaScript development, particularly when dealing with unexpected errors, check out the revolutionary Airbrake JavaScript error tracking tool for real-time alerts and instantaneous insight into what went wrong with your JavaScript code.