3 Handy Spells for the Aspiring ES6 Wizard

Image: Harry Potter FanArt by fridouw

Hermione might have read a whole book on Arithmancy, but the spells that save the day always seem to boil down to Alohamora, Expelliarmus and Expecto Patronum.

Just like every wizard needs her shortlist of handy spells, there are a couple of new Javascript features that might just disarm Voldemort, save Hogwarts, and/or beautify your code every damn day.

Here are 3 particularly magical aspects of ES6 that will brighten your day faster than you can say Lumos!

Arrow functions

In addition to defining functions with the function keyword, you can now define functions using arrow notation.

Old way:

1
2
3
4
function doAThing() {
     console.log(Doing a thing now")
     console.log(“Done")
}

Arrow way:

1
2
3
4
doAThing = () => {
     console.log(Doing a thing now")
     console.log(“Done")
}

(If you’ve used lambdas in Java 8, the setup will feel familiar.)

Arrow functions have 2 simple benefits and 1 complicated benefit.

Simple benefit 1: less writing

We get rid of the function keyword! So fly, so hip!

Simple benefit 2: implicit returns

You can write one-liners like this, without curly braces: returnAString = () => “Here's your string”

Complicated benefit: no re-binding of this

Arrow functions should not be used as a one-to-one replacement for regular functions because they affect the scope of this.

In old-school Javascript functions, this refers to the local scope.

1
2
3
4
5
6
<script>
const div = document.querySelector(.myDiv)
div.addEventListener(click, function() {
     console.log(this) // —> <div class=‘myDiv'> Hi </div>
})
</script>

An arrow function doesn’t create its own context, so the value of this is simply inherited from the parent scope.

1
2
3
4
5
6
<script>
const div = document.querySelector(div)
div.addEventListener(click, () => {
     console.log(this) // —> window
}
</script>

So, be careful about using arrow functions, particularly when using event listeners.

Object destructuring

Object destructuring is super handy. It saves you a lot of writing, and it saves a lot of headaches when it comes to passing arguments into functions and returning values from functions.

Less writing

Old way:

1
2
var thing1 = obj.thing1
var thing2 = obj.thing2

New way:

1
const { thing1, thing2 } = obj

ES6 simply looks inside obj for properties with names matching thing1 and thing2 and assigns the correct value.

Multiple return values

Object destructuring helps us unpack multiple values returned from a function.

1
2
3
4
5
6
7
8
function returnObj( ) {
     return { thing1: 'red fish', thing2: 'blue fish' }
}

const { thing1, thing2 } = returnObj();

console.log(thing1) // 'red fish'
console.log(thing2)  // 'blue fish'

Passing in arguments

1
2
3
4
5
function tipCalculator( { total, tip = 0.20, tax = 0.11 } ) {
     return total * tip + total * tax + total
}

const bill = tipCalculator( {tax: 0.14, total: 200} )

Here, we pass in an object to the function tipCalculator and the argument gets destructured inside the function. This allows arguments to be passed in any order — and you can even rely on defaults so you don’t have to pass in every value.

Var/let/const: variable scoping

ES6’s variable declaration keywords var, let and const allow you to declare variables with a variety of scoping and overwriting rules.

  • var is function-scoped

    • if not declared inside a function, the variable is global
  • let has a block scope

    • the variable is only defined inside whatever block it’s in (including if blocks)
    • you cannot define same variable multiple times using let in the same scope
  • const (“constant”) variables cannot be re-assigned a value

    • properties of a const can be changed though!

The rule of thumb I’ve been using: by default, assign your variables using const unless you know the value is going to change. (I constantly use const!)

This way, I never accidentally overwrite a variable whose value I never wanted to change, and I am forced to make a conscious decision at the outset about how to use variables.

If I want to declare a variable and set its value later (based on if/else logic, for example), I use let. (I almost never use var.)

Summary

ES6 has a ton of awesome, time-saving shortcuts built into it – shortcuts that any worthy wizard would make sure to add to her spellbook. These magical tools aren’t just esoteric/academic fluff — I use them all the time, and I’m a first year myself.

P.S. If you want a tutorial overview of ES6, I’m really enjoying es6.io by Wes Bos (who inspired some of my examples above). The tutorial is easy to follow, and it not only teaches you about ES6’s new features but is basically a Javascript crash course in itself. It’ll totally transfigure your ES6 familiarity!