Fretless

Reasons I Like JS Again: ES6
By Miles Z. Sterrett /

Keep Calm and Hate (Like?) JavaScriptI hated JavaScript. (See my last post.) Hated it - even as my colleagues at Fretless, Davey and Dave, wrote copious amounts of the stuff using various frameworks, and then began teaching week-long JavaScript bootcamps at ElevenFifty.

Oh, I still wrote it, but I wrote it with the attitude of a king condescending to shake hands with his lowliest of subjects. Instead of donning a royal glove, I clothed myself in sneers and vitriol. When Andrew, David, and Missy at OurHealth asked that I stop adding CoffeeScript files to their project, I managed to merely frown. (And then I went to Vim and converted the piece of code I was writing to plain-ol’ JS. Hey, man. Sometimes you appease those with whom you are working on a project. It’s the right, respectful thing to do. … I do think I left one .coffee file in there for them to remember me by.)

Thankfully, JavaScript, the language, receives updates and improvements, much as any other active software project. This June we’ll see the latest release of ECMAScript, the standardized language of which JavaScript is an implementation. It is called ECMAScript 6, ES6, or ES2015. It features what I see as vast improvements to the language. Though much maligning of JavaScript is due to misunderstanding, its current standard still suffers prominent warts that make every day use of the language frustrating for many. ES6 eliminates many of those frustrations, making JS more enjoyable for every day use.

I’m excited to tell you about some of the new features.

Cool, but Not Deal-Makers

There are several very cool additions to JavaScript in ES6. Destructuring assignment, method properties (shorthand), property shorthand, the rest parameter, and the spread operator are all additions I use regularly and enjoy quite a bit. If I didn’t have them, though, I would still be stoked on ES6.

Nonetheless, let’s take a quick peek.

Destructuring assignment


let obj = { x: 'love,' y: 'this', z: 'stuff'}
let {x, y, z} = obj
// x is 'love', y is 'this', z is 'stuff'

Method properties / shorthand


obj = {
  doStuff(x, y) {
    // ...
  },
  didNotHaveToTypeFunction() {
    // ...
  }
}

Property shorthand


let x = 1
let y = 2
let obj = {x,y}
// obj = { x: x, y: y }

Rest parameter


function f (x, y, ...a) {
  return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9

Spread operator


var params = [ "hello", true, 7 ]
var other = [ 1, 2, ...params ] // [ 1, 2, "hello", true, 7 ]
f(1, 2, ...params) === 9

Cool stuff, right? But you can probably live without it.

Favorites

There are a few additions to JavaScript in ES6 that really made me enjoy writing “pure” JavaScript again. They have made the language feel more complete to me. Without string interpolation, block-scoped variables and functions, import and export of modules, and arrow functions I don’t think I’d be enjoying writing JavaScript as much. I haven’t even been missing CoffeeScript! (Many of these things are features of CoffeeScript already.)

String interpolation

Big deal. String interpolation. I mean, just concatenate stuff like the rest of the world and quit being a pansy, right? Why isn’t this in the “cool but not a huge deal” section?

You’ve heard the deal with no brown M&Ms and Van Halen, right? Van Halen was putting on giant shows that required 9 semis of equipment, etc. Things had to be constructed just so. If not constructed properly, the stage setup was literally life-threatening. In their contract (essentially) was a note that they required a bowl of M&Ms without any brown ones. If a member of Van Halen noticed a bunch of brown M&Ms in their M&M bowl, they knew they had to double-check every single aspect of the show’s set, or a disaster could take place. It was an indicator that the venue did not take their contract seriously. If they can’t be bothered to remove some M&Ms, did they bother to get amperage right? Did they make sure their flooring could support the weight of the stage? (See Snopes.)

String interpolation is like that bowl of M&Ms for me. If there’s not even string interpolation, why would I build something equivalent to a 9 semi show using that language?

Example:


let band = "Van Halen"
let title = `I don't even like ${band}, but damn do I like that story.`

Block-scoped Variables and Functions

JavaScript - ES5 and earlier - uses function-level scope. This can result in surprising behavior for many, as it is not typical of other languages. (Python actually has function-level scope as well. I assume others do, too, but remain blissfully ignorant.) It means you can do something like this, and it’s totally legit:


console.log('foo' in window) // true
var foo

… or …


for (var i = 0; i < 3; i++) {
  var j = i * i
  console.log(j)
}
console.log(j) // 4

Now, using the let or const keywords in place of var, that ‘j’ above would not exist in the final console.log - as it should be.

A full explanation is outside the scope of this post, but check out ECMAScript 6 and Block Scope and the Wikipedia article on scope.

Import / Export

We can load modules today in the CommonJS way.


var thing = require ('some/thing')

I’m going to put my fingers in my ears and sing nursery rhymes if you try to debate with me whether CommonJS is really the right way or we should be doing some other thing. Forget about it.

ES6’s import and export functionality make loading modules much more intuitive.


// a file at js/component/widget.js
let widget = {
  render() {
    return '<div><h1>Widget</h1></div>'
  }
}
export default widget

// a file at js/app.js
import widget from './js/widget'

// ...

See? JavaScript is all grown up now!

Arrow functions

Inspired by CoffeeScript, the fat arrow function is here! If you’re not familiar, arrow functions are not only a fun and enjoyable alternate syntax for writing a function. It also comes with lexical this. Instead of having to do something like:


var self = this
doThatCallbackThang('now', function(whatsit) {
  self.doAThingOnTheObjectIWasIn()
}

… you can just do:


doThatCallbackThang('now', (whatsit) => {
  this.doAThingOnTheObjectIWasIn()
}

The old syntax and scope of this is not going away. You just have the option of using the arrow function if you wish this to still be this in the anonymous function you’re writing.

These four additions matured JavaScript instantly for me. Removing a few stresses, a few gnats buzzing at my ear, has made every-day work in the language much more enjoyable on average. On top of that, ES6 is backward-compatible! You don’t have to worry converting all of your old code to be ES6-friendly. It’ll be fine the way it is - a special butterfly that should probably be preserved under glass (and then shoved in the back of a closet).

ES6 is backwards compatible because the web can't break the Space Jam website. It's a national treasure. —@stevekinney — yung java$cript (@tomdale) April 23, 2015

Many ES6 features have been implemented by the latest browsers, but if you want to run everything today, you’ll need something like Babel to transpile your perfect ES6 into a mixture of already-implemented-ES6 and the ES5 equivalent.

If you’d like to read more, one place to start is to watch hacks.mozilla.org for their ES6 in Depth series. I enjoyed their introduction. They’ve since released Iterators and the for-loop and Generators. Many of the code examples here were taken straight from ES6-features.org. Be sure to go there to see more examples, including many of features I didn’t cover here.

Are you as excited about ES6 as I am? What is your favorite feature?