I started a project a few weeks ago, and decided it was high time to give ES6 / ES 2015 a whirl. This is just the practical set of stuff I used getting started, and how I thought about the differences – mostly just syntax highlighting with a little bit of ‘how to organize your JS’. Official terms, nomenclature, and ‘the right way’ aren’t always my forte, but getting the job done is, and this is no different. If you’ve used ES6 before, you probably already know most of this, and might even be able to correct me on some of it.
Comparison
If you’re just looking for an example, below is a direct side-by-side comparison of a I pen I re-wrote ES6 with the same exact functionality. It’s a good starting point for direct comparison.
- Here’s the original pen (here for just the JS)
- Here’s the pen in ES6 (here for just the JS)
Setup
The easiest way to get started right off the bat with ES6 is to use CodePen, and select the “babel” as a Javascript preprocessor.
Variables, let, const, var and globals
There’s been some debate over some of this (it’s a bit more complex than a 1-1 change), but here’s what I’ve gathered:
var
declares a function-scoped variable, and
let
declares a locally, block-scoped variable
const
declares a read-only variable, meaning you can’t do this const = "foo"; const = "bar"
.
Basically
let myVariable = "dustin"
is the new var myVariable = "dustin"
const myVariable = "dustin"
is a new never-changing variable
When to Use
Just use let
everywhere you would have used var
.
Strings, variables and template literals
The back-tick is the new cool kid in town when it comes to strings. When you want to combine variables, or even logic with a string, you no longer have to use quote and +
, you can simply wrap the string in a `
(back-tick) and then wrap any variables or logical with ${}
. This makes concatenation a breeze. You can also do multi-line strings.
Basically
"my name is" + user.name + user.lastname + " ."
can be simplified to `my name is ${user.name user.lastname} .`
When to Use
Anytime you need to combine variables with strings, use back-ticks `
and ${}
.
Arrow Functions
For me, arrow functions were kinda ES6’s poster-boy. Mostly because they look so…functiony. There’s a few different ways you can write them (more shorthand options), but it’s all basically just replacing the word function
with =>
. Bewares though, this changes the scope of ‘this’ (see below).
Basically
// old function expression
var something = function(){ //do something }.
// new arrow function expression
let something = (parameters)=> { //do something }.
When to Use
Anytime you’re writing a function that you don’t want to have a new this scope, use an arrow function (see below).
This, Scoping with Arrow functions
The scoping of ‘this’ is a bit different when using an arrow function. Put on your seatbelt: describing the Javascript keyword this while using the English demonstrative, this, gets a little hairy. Basically using an arrow function will pass this
on through so that this = this
. It’s still lexically scoped - meaning block-level stuff.
The way you’re used to a new “this scope” being created every time you use the word “function”, still works the same, but doesn’t happen when you use an arrow function.
Basically
// old stuff
$('a').click(function(){ console.log(this) }) // returns what you’d expect - what was clicked, in this case 'a'
// ES6
$('a').click((e)=>{ console.log(this)} // returns the parent’s value for 'this', e.currentTarget returns what was clicked
// old stuff equivalent
var t = this; $('a').click(function(){ console.log(t); } // essentially the same but without the messiness.
When to Use
Anytime you’re writing a function that you don’t want to have a new this scope, use an arrow function. You can use event.currentTarget
for to get the clicked object in a click handler. Really helps with writing modular JS (below).
Modular stuff: imports, classes, extends, constructors, etc.
We’re gonna get a little hairy on some of the more opinionated js stuff, but here goes: Remember when Sass first hit the masses, and people started using @import again to organize, and modularize their css/sass because it didn’t require an additional request? Well, you can basically do the same thing using imports and classes. Structurally, I’ve got one main.js that handles the loading/instantiation of everything, the separate independent modules. Like this:
- main.js
- modules
- _carousel.js
- _myFunction.js
- lib
- jQuery.min.js
- waypoints.min.js
- gsap.min.js
Basically
I’d put these two lines in my main.js ( what I use to instantiates/call everything else)
import myFunction from './modules/myFunction'
// On document load, or ready or whenever I want to run it
let myFunction = new myFunction();
Then in each module (_myFunction.js), I’ve got an init function that runs when it’s called so, and you wrap everything in a class export, using the constructor method (a special method) to start things off – like so:
export default class {
constructor(){
this.init(); // Run the init whenever invoked
}
init() {
// do something
}
}
When to Use
For me, life is much clearer when I write my JS in a modular way (there’s several options, above is just one example). You’ll love it for the clarity, consistency, and readability it brings your JS.
Other stuff
There’s also a couple of things that help for dealing with numbers (I haven’t yet come across the need for them) like spread operators and rest parameters. Check out the links below for more on those.
Resources
A decent guide to setting up an ES6 / ES 2015 workflow
Airbnb’s JS style guide
Css trick’s write-up on learning es2015
Wes Bos’ course - Probably the most reputable training course/guide to ES6. It’ll run you around $100, but well worth the investment if you’re wanting to go deep.