This article is part of my series Visualization with React. Previous article: React and D3 – similarities and differences
In this guide, I will use ES6 notation whenever I would normally do it in my day job. There are many, many differences in ES6 compared to previous versions of javascript and that can be daunting. But in this time and age, a lot of code you can run into is going to be written in ES6, so a cursory knowledge of some of its features can go a long way.
Here are the features I use most often:
Fat arrows functions
ES6 introduces a new, more concise way to write functions. Instead of writing:
function add10(d) {return d + 10;}
one can write:
var add10 = d => d + 10
Technically, those two forms are not completely equivalent. The main difference is if you need to use the context keyword this. But in most cases, fat arrows are a much more concise, and therefore more legible syntax.
To do a function which takes more than 1 argument, wrap them in parentheses like so:
(a, b) => a + b
For a function with several statements, you must use curly braces like a regular function, and use return if needs be:
d => { console.log(d); return d; }
For a function that returns an object, wrap that object in parentheses to avoid confusing it with the previous form:
d => ({key: d})
const and let
Before ES6, to declare variables, you could only use the var keyword.
var a; var b = 10;
In ES6, you can declare variables using const or let. When you use const, the variable cannot be reassigned:
const a; // error - a must be assigned a value
const b = 1; b = 2; // error - b can no longer be reassigned
Variables declared with let can be reassigned.
let a; // ok a = 10; // ok a = 20; // still no error
const and let are more expressive than var, because they specify whether we plan to change the value of a variable or not. They have another advantage: they are scoped. They can be used inside of an if branch, or a for loop, and not be accessible outside of it. Conversely, var are not scoped – they are available everywhere within the function where they are declared, or globally if declared outside of a function.
So, there’s no reason to ever use the var keyword in ES6.
Spread operator
In ES6,if you have an array inside another array, you can replace that array with its items in sequence using the spread operator. An example would make this clearer:
const a = [1, ...[2, 3, 4]]; // [1, 2, 3, 4].
That may seem like not much but it’s super versatile and useful. For instance, instead of concatenating two arrays, you can write:
const a = [1, 2]; const b = [3, 4] const c = [...a, ...b]; // [1, 2, 3, 4]
Interestingly, it works with empty arrays:
const a = [1, 2]; const b = []; const c = [...a, ...b]; // [1, 2]
But not with primitive literals (numbers, etc)
const a = [1, 2]; const b = 3; const c = [...a, ...b]; // error
Instead of pushing an item to the end of an array, you can also use the spread operator:
const a = [1, 2]; const b = 3; const c = [...a, b]; // added benefit - creates a new array instead of changing it in place.
Note the difference between these 2.
[…[1,2], 3] will work;
[…[1, 2], …3] will not.
Composing arrays like this can be conditional!
const a = [1, 2]; const b = 3; const condition = false; const c = [...a, ...(condition ? [b] : [])] // [1, 2];
What just happened? just like above, but we applied the spread operator to the expression which is in parentheses. If the condition were true, that expression would be equivalent to [b]. But since it’s false, it is equivalent to an empty array.
An experimental feature of ES7 extends the spread operator to objects.
const obj = {key: 'a'}; const newObj = {...obj, value: 1}; // {key: 'a', value: 1}
Destructuring assignment
You can do more stuff with objects in ES6. Destructuring assignment covers a number of nifty features but here are the two I use the most.
const obj = {key: 'a', value: 123}; // you can read several properties from an object at once and assign them to variables: const {key, value} = obj; console.log(key, value); // 'a', 123
Before ES6, you had to write a function like this:
function div(num, den) {return num / den;} div(6, 2); // 3; div(2, 6); // 0.333333 order of the parameters matters! div(3); // NaN - can't forget an argument!
In ES6, we can expect the function as argument to take an object and access its properties:
function div({num, den = 1}) {return num / den;} div({num: 6, den: 2}); // 3 div({den: 2, num: 6}); // still 3 div({num: 3}); // still 3 - den has a default value
Using an object, we don’t have to remember in what order the function parameters have to be provided.
Wrapping it all together
what’s another form for the last function I wrote?
const div = ({num, den = 1}) => num / den;
In the next article in the series, Coding with React, we will finally start to write some React code.