• Published:
  • Under: Development

It has been four years (June 2015) since ES6 was released, but it still is a very significant version for ECMAScript. While it has been out for some time, some developers are still reluctant to make the leap since not all browsers offer complete support, and transpiling is required to ensure full compatibility. If you are one of those developers, hopefully this will demonstrate the value in adopting features from ES6 (and beyond). Following are five of the best features ES6 has to offer, with an explanation of how to use each:

  1. Arrow Functions
  2. Let & Const
  3. Promises
  4. Classes
  5. Default Parameters (or Destructuring)

Arrow Functions

One of the biggest standouts when looking at modern JS is the prevalence of arrow functions. They serve as an alternative to the function keyword and are named due to their use of => as a delineator of input parameters and return body.

While syntactically different they also have an effect on scope. Inside an arrow function, this does not get redefined. This allows you to access the this from the parent scope without having to previously define a new variable for it. This is very important to keep in mind as it will have an effect on the decision to use an arrow function instead of a regular function. A good example of when not to use it would be in an event listener callback which defines it’s own this.

// Old Way
function add( a, b ) {
  return a + b;
}

// New Way
const add = ( a, b ) => {
  return a + b;
};
// New Way Simplified
const add = ( a, b ) => a + b;

/** Lexical This **/
// Old Way
var self = this;
this.nums.forEach( function ( v ) {
  if ( v % 5 === 0 )
    self.fives.push( v );
} );

// New Way
this.nums.forEach( v => {
  if ( v % 5 === 0 )
    this.fives.push( v );
} );

 

Let & Const

In practice, let and const replace var. As the name suggests, const declares a variable as being constant which means it can’t be reassigned to something else. That is not to say it is immutable because the properties of the object or values of an array can be mutated (changed).

When the variable needs to be reassigned let must be used. This is a signal that the variable will be re-assigned later in the code which is often the case when using loops (counting for instance).

With these two at your disposal, there is really no need to ever use var again, but it is still there if you so wish to use it.

Promises

Promises serve as an entryway to leveraging the true power of JavaScript: asynchronicity. Abstractly, a promise is exactly as it sounds: a promise that I will return something to you later. When created, it begins processing but allows the script to continue on and handle the response whenever it is received later.

A promise is created by constructing an instance of Promise with a function that takes two functions as arguments: resolve and reject (optional). In the function body, you can then call resolve to complete the promise and return the result. Alternatively, if there was a problem you can call reject to trigger an error.

On the promise instance itself, you can then chain .then to handle the resolved result and likewise .catch to handle the reject (error) result.

const sayHello = new Promise( ( resolve, reject ) => {
  try {
    setTimeout( resolve( 'Hello' ), 2000 );
  } catch ( err ) {
    reject( 'I got an error!' );
  }
} );

sayHello
  .then( result => console.log( result ) )
  .catch( err => console.error( err ) );

 

Classes

JavaScript now has an even more object oriented feel with the introduction of classes. What was once done with prototyping can be accomplished much cleaner with a class. Classes are written in the same way that most other object oriented languages do it. You have the declaration preceded by keyword class followed by the class body enclosed in braces. Classes can also extend other classes. When a class is constructed, arguments can be provided and will be passed to the constructor function if one was defined for the class.

// Old way
function Foo( x ) {
  this.x = x;
  this.y = 432;
}
Foo.prototype.point = function() {
  return 'Foo(' + this.x + ', ' + this.y + ')';
}

var myfoo = new Foo( 99 );
console.log( myfoo.point() ); // prints "Foo(99, 432)"

// New Way
class Foo {
  constructor(x) {
    this.x = x;
    this.y = 432;
  }

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

let myfoo = new Foo( 99 );
console.log( myfoo.point() ); // prints "Foo(99, 432)"

 

Default Parameters

A great nicety are default parameters which allow you to define the default values for parameters when declaring a function. Previously, arguments would need to be tested for undefined and then set with the default value. Now, this all happens automatically simply by assigning parameters a value inside the initial parameter declaration of the function.

// Old Way
function multiply( a, b ) {
  if ( typeof a === 'undefined' )
    a = 0;
  if ( typeof b === 'undefined' )
    b = 1;
  return a * b;
}
console.log( multiply( 5 ) ); // 5

// New Way
const multiplyES6 = ( a = 0, b = 1 ) => a * b;
console.log( multiplyES6( 5 ) ); // 5

 

Bonus: Destructuring

Nearly tied with default parameters was destructuring. Destructuring allows you to pull properties out of an object and into variables. This works similarly for arrays as well. For objects, the variable name must be the same as the property key.

// Old Way
var arr = [1,2,3];
var arr0 = arr[0];
var arr1 = arr[1];

// New Way
const arr = [1,2,3];
const [arr0, arr1] = arr;

// Old Way
var obj = { a: 1, b: 2 };
var a = obj.a;
var b = obj.b;

// New Way
const obj = { a: 1, b: 2 };
const { a, b } = obj;

 

Conclusion

ES6 was a fantastic and revolutionary update to the language. These are just a handful of the most impactful changes, but there are many more that would be beneficial to explore.

If you want to dive deeper, visit http://es6-features.org for a collection of examples that correlate with the changes above including features not mentioned here.  

As of writing this, JavaScript is now at ES9 so the features mentioned here are just the start. For instance, in ES8 async and await were added which take promises to a whole new level. Take advantage of modern JavaScript to get the most out of the language and make the development experience that much more enjoyable!

Have tips of your own for mastering ES6? Share them with us on Twitter, or subscribe to our newsletter for more content like this!