Introduction to ES6 — Part 1

ECMAScript 2015, or ES6 is the newest iteration of JavaScript. ES6 is slowly being implemented amongst all the different JavaScript runtimes, but eventually ES6 will be the new standard and with it comes a fair number of new syntax changes. I’m just going to be talking over a few that stuck out to me as especially interesting (each one has a link to the MDN page if you want more information).

Destructuring

Destructuring allows us to easily extract data from an array/object and define it with a new variable.

var list = ['cat', 'dog', 'bird'];
var [steve, izzy] = list;
steve; // equals 'cat'
var obj = {dog: true, cat: false};
var {sam, clyde} = obj;
sam; // equals true

An extremely powerful use of destructuring comes in to play when we want to call a function that takes a large object as a parameter. By using destructuring we can easily just grab the parameters we are interested in. See below (keeping in mind that with a click the event object could be very large).

$.on('click', function({para1, para2}) {
addPetName(para1,para2);
});

Spread Operator/Rest Parameter

The spread operator (…) spreads out some expression into its individual components when it makes logical sense (arrays, function calls, etc).

var nameCats(a,b) {
// do some code
};
var names = ['Roberto', 'Sunny'];
nameCats(...names);
// Using the spread operator with Rest parameter
var findAllOwners = function(cat, ...rest) {
rest.forEach(function(str) {
console.log(cat[str]);
});
};

As you can see the rest parameter also allows us an easy way to capture however many unnamed function parameters we want to. Using our example above findAllOwners(cat, x, y, z) would have rest = [x, y, z]. Additionally another benefit from using the spread operator is we can call a function that is expecting a value using each element of an array very easily.

Default Parameters/Template Literals

Default parameters just give us a simpler way of passing in default values if none are given. Template Literals give us a convenient way to call variables inside of strings. An additional benefit of template literals are that they allow us to more easily put white space in our code for clarity.

var generateCat = function(name, age, location='Portland') {
return `${name} is ${age} years old and is currently in ${location}`;
// The key to note is that in this case you have to use backticks ``
};

Arrow Functions

Arrow functions are just a simpler, shorter syntax for writing functions. One additional advantage is that they automatically bind the ‘this’ keyword to the enclosing context’s ‘this’ value.

var add = (a,b) => {
return a+b;
};
// is the same as
var add = function(a,b) {
return a+b;
};

For … of Loops

For…of loops give the ability to quickly write out iterations going through every value on an array, set, map, etc. Do note that you cannot use for…of loops with an object, it will throw an error.

var cats = ['steve','clyde','harvey','michelangelo'];
for (var val of cats) {
console.log(val);
}
// would log 'steve' then 'clyde' and so on

Maps/Sets

Maps and sets are two new data types introduced in ES6. They are very similar to JavaScript Objects, but are different for some very key reasons. There are also weakmaps and weaksets, but they are beyond the scope of this blog post.

The main difference for maps is that they allow you to use any primitive data type (boolean, number, etc) as a key, not just strings like a regular object. Additionally you can use a for…of loop on a map. However, maps use setters and getters as well as some additional methods to handle their data.

var pets = new Map();
pets.set("clyde", "cat");
pets.set("sam", "dog");
pets.get("clyde");
// equals "cat"
pets.size;
// size equals 2
pets.has("sam");
// returns true
pets.delete("clyde");
// removes "clyde" from the Map
pets.clear();
// empties the map

Sets on the other hand are merely a list of unique values. Sets have similar methods to Maps (set, size, has, delete, etc), but they only store unique values. When they are iterated over they maintain the insertion order of all of the elements, however they can’t be accessed like an array (set[1] does not work). Other than only storing unique values, the other major benefit to sets is that they allow you to delete values from a set merely by their value, not their index. This would allow constant time (O(1)) complexity to remove a value.

var flavors = new Set(["chocolate", "vanilla", "strawberry", "chocolate", "pistachio", "vanilla"]);
console.log(flavors);
//yields ["chocolate", "vanilla", "strawberry", "pistachio"]
flavors.add("mint chocolate");
pets.delete("pistachio");
// constant time removal

Let/Const

Const values assign a variable to a one-time value. They cannot be reassigned. It is good practice to name const values in all uppercase. Let values on the other hand allow you to define a variable only locally. So using var defines a variable globally or within the scope its in, but using let only works within a block/function scope.

const MY_DOG = 'izzy';
MY_DOG = 'sam'; // this will silently fail
console.log(MY_DOG); // logs 'izzy'
if (sam.age > izzy.age) {
let dogToWalk = 'izzy';
}

Transpiler/Linter

At this point you’ll still need a transpiler to compile your ES6 code back in to ES5 to ensure that all JavaScript users are able to interpret your code. There are many to choose from, but Babel has the lion’s share of usage. If you have a linter, it’s going to look awful when you start writing ES6 code. Be sure to download babel/es6 linter for your text editor.

Conclusion

I hope you are as excited about ES6 as I am! Just try using Babel’s REPL to see how efficient and clean your code can be in ES5 compared to ES6. There is much more to ES6, but I hope this was enough to get you excited to learn more. Let’s together start using ES6 to write cleaner, better code!