Javascript ES6 For The Win! (Part 1)

This post is the introduction of our series about Javascript and related tooling.

Start Your Engines

Unless you live under a rock or in a very dark cave without any Internet connection yet, you probably already heard about Javascript ES2015, Harmony, ES6 or even ES7.

Here at MYOB we also recently caught the buzz and it was not long before we started introducing it into some of our projects.

So what is behind those barbaric codenames ?

In a nutshell ES6 and ES7 are the acronyms used by the ECMAScript technical committees to encompass the features they are designing for the next iterations of what most of us call the programming language JavaScript (Update: ES6 has been approved and is now officially ES2015 !). What we use today is sometimes referred as ES5, and what we are starting to see implemented in browsers of late comes from the ES6 specification. Many of ES7 features are still just propositions - drafts that may or may not see the light of day - but some obvious features likely to make it are already adopted, thanks to transpilers.

Wait a second here. What is that transpiler thing ?

Transpilers are what makes this post possible today. Without transpilers and transpilation you couldn't seriously consider writing ES6 or ES7 code for production today as most new JavaScript features are either missing from browsers or only available on evergreen ones.

Transpilers

In the wild, there are two main open source contenders that bring us today the JavaScript of tomorrow. Namely:

Both are worthy of your attention but at MYOB we chose to use Babel as it offers ES6 syntax but also some extra cutting edge ES7 features and React JSX support among others.

If you are transpiling code, why not use CoffeeScript or TypeScript ?

CoffeeScript has been around for a while and offers an elegant alternative to JavaScript syntax and works a bit like the aforementioned transpilers. During your build the CoffeeScript compiler converts your CoffeeScript syntax into current ES5 JavaScript syntax.

Notwithstanding the above CoffeeScript is not JavaScript and so you will need to learn both languages to use it effectively (at least for debugging).

JavaScript is also a safer option when you want to share code with the community and several libraries originally written in CoffeeScript moved back to JavaScript for that very reason.

TypeScript is great and offers a lot of good features. There, I said it. The interfaces, the static types, decorators/annotations and pretty much every feature in the ES6 handbook are available. It builds on top of ES6 and transpiles your code into current ES5 JavaScript as well. It is also a prime choice for people considering Angular 2.0.

However this is not pure ECMAScript standard. Some people will prefer to stick to JavaScript as it is, and will be, more than starting to rely on features that may never be. But this is really a matter of preference here. I think TypeScript (and ES6/ES7 to a lesser degree) facilitates the on boarding of C# and Java developers as you can't help but notice the similarities in syntax between those.

What features do we get with those ES6 transpilers then ?

If people are getting so excited about ES6 and transpilation nowadays is that they recognize some major benefits. First of which is the reduction in boilerplate code. But this is also about productivity features, more traditional OOP and better scoping.

Features You Might be Craving For

Taken directly from the Babel website, here are some of the most useful additional features you can use in your JavaScript today with a transpiler:

  • Classes
// Before:
function Fruit(size, age, colour) {  
  this.size = size;
  this.age = age;
  this.colour = colour;
}

Fruit.type = function() {  
  return 'This is a fruit.';
}

function Banana(size, age, colour) {  
  Fruit.call(this, size, age, colour);
  this.peel = true;
}

// Still requires a recent browser for the following line
Banana.prototype = Object.create(Fruit.prototype);

Banana.prototype.open = function open() {  
  this.peel = false;
}

----------

// After:
class Fruit {  
  contructor(size, age, colour) {
    this.size = size;
    this.age = age;
    this.colour = colour;
  }

  // Class methods - static methods
  static type() {
    return 'This is a fruit.';
  }
}

class Banana extends Fruit {  
  contructor(size, age, colour) {
    super(size, age, colour);
    this.peel = true;
  }

  open() {
    this.peel = false;
  }
}
  • Arrow functions
// Before:
something.on('start', function(bananas) {  
  return bananas > 10;
});

----------

// After:
something.on('start', bananas => bananas > 10);  
  • Constants
const MYCONSTANT = "After declaration no changing";  
  • Default parameters
function myfunction(value, option = 'default') {  
  // If you call myfunction(value), here option will be equal to 'default'
  // Replaces your good old: option = option || 'default';
}
  • Template literals
var company = 'MYOB', language = 'Javascript';  
var messsage = `${company} uses cutting edge ${language}.`;  
// message will be interpolated into 'MYOB uses cutting edge Javascript.'
// Replaces your good old: message = company + ' uses cutting edge ' + language;
  • Let scoping (replacing var in many cases)
let x = 10;  
{
  let x = 20;
  // Inside the block x can be redefined
}
// Outside of the scoped block x = 10
  • Modules
// In a fruit.js file
export default function eat(fruit) {  
  return `You eat a ${fruit}.`;
}

// In a main.js file
import eat from 'fruit';  
eat('Banana');  
// The function will return 'You eat a Banana.'
  • Class properties (ES7 - draft)
// Instead of creating properties in the class constructor like so:
// this.size = 0;
class Fruit {  
  size = 0;
  age = 0;
  colour = 'white';
}
  • Computed property names
var namespace = 'MYOB';  
var something = {  
  [namespace + '']: 'dynamic naming'
};
// something['MYOBid'] or something.MYOBid return 'dynamic naming'
  • Decorators (ES7 - draft)
// Based on Yehuda Katz proposal (EmberJS Core team member)
@memoize
function calculate(x, y, z) { ... }

// Example of a computed property
class Person extends Model {  
  @readonly
  name() {
    return `${this.firstName} ${this.lastName}`;
  }
}

Many other features are available - similar to constructs you might be used to in languages such as Python, like array comprehensions, generators, destructuring, object rest/spread...

Sounds good. How Do I Get Started ?

There are several ways to get Babel into your projects today and the beauty is that you don't have to change any of your existing code to start using it. ES6 and ES7 are just extensions of the original ES5 syntax you already use and the transpiler will not touch your existing code so will only convert your new syntax to ES5.

Head to the Babel website to discover the numerous way you can integrate transpilation in your build pipeline. From the command line to an IDE like Webstorm (recommended IDE for JavaScript) and of course our usual suspects: Grunt, Gulp, Broccoli... There are no shortage of options.

(In the next post we will be presenting one such option to help you get started.)

We did not cover NodeJS or IO.js here today, but it is worth mentioning you can also use Babel to write ES6 code for the backend. Those platforms are also slowly moving to ES6 (the latter faster than the former) and some features are available out of the box or behind flags.

Wherever you do JavaScript today, think forward, use ES6 :-) !

Ready to use Babel ? Read on part 2 of the series.

Cover image by Chris Williams [Public domain], via Wikimedia Commons (modified)