. In my previous post, I explained that we are soon to see a language that will incorporate more object-oriented principals and functionality that’s been sorely missed, such as the new scoping, classes, getter and setter properties and inheritance. Although seemingly impressive in number and ability, these are only a few of the features we can look forward to for ECMAScript Version 6. In this post, I aim to dig deeper into the new keywords available to developers and will wrap up by taking a look at what browsers presently support what features.
New Keywords Available to Developers
We’ll start off with a feature that’ll simply save time and reduce some of the repetitive clutter from scripts. ‘Object Literals’ doesn’t make major changes to your code, but simply provides a short-hand notation in place of the current object construction process. Let’s take a look at the following example from the current ECMAScript 5 implementation:
Figure 1 - Object Construction in ECMAScript5
In the new ECMAScript 6 form, we can rather write this as:
Figure 2 - Object Construction in ECMAScript6
Although there’s nothing earth-shattering about this new notation, it does reduce repetition in one’s code and improve the overall readability of the script. Note that the usual rule with regards to keywords applies: you cannot use any reserved words for your property name.
Default Property Values
When defining a function, a number of parameters will need to be passed in. However, some use cases will call for a differing number of parameters for any given scenario, so traditionally we’ve had to either create multiple functions to handle this or expose all possible parameters and apply some sanity checking to ensure that the properties we do need for any given use-case are available. Sometimes this means that all the parameters are populated; sometimes we fill in the gaps where a value wasn’t passed in, after checking other dependencies.
ECMAScript 6 aims to simplify this and introduces the concept of default parameters values. Let’s look at our car example from earlier and expose the type parameter. We’ll do another comparison between how this would look today and then see how ECMAScript 6 simplifies it:
Figure 3 - Handling Parameters
Figure 4 - Optional Parameters & Object Literals
Notice the wild improvement in readability. Not only can we clearly see what the default values will be for each parameter right there in the first line, but we can drop three dense lines for a clean return statement.
This serves as another short-hand notation style, but has a more impactful difference on our code readability than the object literals do and when used in conjunction with each other, our scripts become significantly easier to parse by eye.
ECMAScript 6 introduces a new concept to cope with this called ‘Rest Arguments’. In this case, rather than have a function with these pre-defined arguments (or lack of), you will use an ellipsis before the parameter to indicate that all other parameters passed in will be found within an array given this parameter’s name. Take a look at the following example to see how this is done:
Figure 5 - Using a Rest Parameter
In this case we place the ellipsis before the num parameter, causing all additional parameter values to be placed within an array called num. From here, we can easily iterate through the values to return the sum of the parameters.
You might be thinking, “But Whit, why would I use this instead of just passing in an array?” Good question. Pretty much it boils down to readability. You might use a parameter like 'numberArray' that self-describes that it’s an array of numbers being passed in, but this just as easily allows the developer to see from the first line that no matter how many elements you pass in, they’ll be available within an array. You can also use additional parameters when creating your function; simply put these at the front with your rest parameter at the end to capture the remainder of the values passed in.
Data Structures – Sets and Maps
We’ve got new data structures in ECMAScript 6! Specifically we’ve got sets and maps. Sets are quite similar to arrays, except that every value stored within the set will be unique. Let’s look at an example:
Figure 6 - Set Example
Now, let’s step through this a bit at a time so we can understand what’s going on. First we create the new ‘Set’ object, then add a number of cars to it. Note that I intentionally added a duplicate to the end. If this were an array and I were pushing each of the elements into it, we would have a duplicate at the end, but because each value within a set is unique, it will not store a duplicate.
Additionally, when we delete the Lamborghini from the set, it’s completely gone since there was only one to begin with. When we use the has function to check to see if the set still contains the value, it returns false, as one would expect.
We also have maps, which are quite common in other languages. They work similar to a Dictionary in C# or a Hashtable in Java in that they are key/value pairs. We have a number of unique keys that we provide and when queried, it returns the value paired to that key.
Figure 7 - Map Example
In here, we create the new ‘Map’ object. First, because each key much be unique, I set two pairs to share the same key. In this case, the DB9 value will overwrite the original, because again, I can’t have non-unique keys across all the pairs. However, I can have duplicate values since the keys are different. Within ECMAScript 6, the keys aren’t restricted to simply being strings though – rather, they can be any data type, including objects, numbers and even undefined, should you choose to live dangerously. At the bottom of the example, I show what the output of this ‘Map’ object looks like.
Destructuring in ECMAScript 6 allows us to utilize both array and object destructuring. This is essentially another shorthand function that allows us to easily initialize variables at one point and even re-order them without having to create the intermediate steps ourselves.
For demonstration purposes, we have a third-party function that returns information about the current date, but doesn’t return the values in any common-sense order, nor are they named anything particularly useful, as they’re just dumped into an array. For the sanity of our own developers, we want to reorder these values in a more sensible way and we can use ‘Array Destructuring’ to do it. Observe the following example:
Figure 8 - Array Destructuring
We retrieve the value from the oddDate() function and observe that it’s just an array. ‘Array Destructuring’ allows us to split apart this array and define multiple values to match parts of it in a single line. Since we don’t care about some of the values, we simply place a comma in their place to ignore them, then place a variable in those array indices that we do want to retrieve the value for. Finally, to indicate that this is working, we output each of the values and form a short date.
However, destructuring isn’t only limited to arrays – in ECMAScript 6, we can apply this concept to objects as well. Observe a similar example:
Figure 9 - Object Destructuring
Where the previous implementation of oddDate() returned an array, this version returns an object, but we destructure it in a similar way – simply create another object patterning the returned property names as our own object property names, then provide our local variable for each as the value. On the next line, observe as the values yield the desired short date output.
While another shorthand utility, this one can easily remove a number of repetitive and error-prone lines in which we might have otherwise looped through the object properties. Combined with the getter and setters for properties to do value sanity checking that I covered in the last version of this blog, this can significantly aid developers in producing more readable code with shorter turnaround time.
Prior to ECMAScript 6, for example, let’s say that we have a list of fruit objects that consist of names and colors. We want to create a map that simply extracts each of the colors from all the fruits. The map() method will produce an array that takes in a callback function to which we’ll pass each of the elements and finally produce each of these colors. Prior to ECMAScript 6, we might define such an operation with the following:
Figure 10 - Using the map() function today
However, arrow functions are awfully useful when it comes to defining the functions that are used for callbacks (or really any other function). In this case, we’d simplify this with the following:
Figure 11 - Using map() in ECMAScript 6
In this case, we have exactly the same thing, but have simply dropped the text “function” and “return” from the script. An arrow function will work whether you intend to return a value or not. But what would you do if you wanted to define a function that takes more than a single value? See the below example with the current function definition on the left and the arrow format on the right.
Figure 12 - Comparison between function definitions
Functionally, either of these formats yields the same end result, but imagine you’ve got a more complicated function and you can see how the readability has improved by removing the extraneous text from the script.
When a promise is defined, it is either fulfilled or rejected. At this point, another function will run for either case, whether this be to perform an asynchronous action or to handle an error that’s cropped up. Either function will then return a value to the pending promise object that will handle the result in either the then() function (to indicate success) or the catch() function (to handle an error).
Figure 13 - Promise Example
Here we define a promise that’ll simply perform the setTimeout() operation for a random amount of time from 1 to 5 seconds, then writes to the console with the promise identifier and time. When the promise resolves, it’ll indicate that the promise (identified by its identifier) is finished. In this case, we can see that, in order from least to greatest, we have promises #4 at 1620ms, 1, 2, 5 and 3 at 3877ms. This is the order that the promises should complete in as they don’t do anything but set the timeouts for that length. And what do you know? That’s the order in which the output is written to the console indicating that each has finished.
Additionally, note the use of the arrow shorthand functions to simplify the notation to define each of the functions within this example.
Over the course of this blog, we’ve covered a large number of features being made available in the upcoming ECMAScript 6 release, generally those in terms of improving readability and simplifying existing operations. The Sixth Edition adds significant new syntax for writing complex applications. While there are still other concepts I’d like to cover, the implementation format continues to evolve even today and the functionality isn’t necessarily available in the ES6 transpilers we have, such as tail call optimization, Weak Maps and Sets, Proxy objects, reflection, sub-classing and even some of the variations on the functionalities I’ve presented.
Additionally, should you be interested in trying out any of the examples I’ve covered in this blog post or the previous one, you can easily do so utilizing a transpiler like Traceur (https://github.com/google/traceur-compiler
). While you can utilize this tool (or others) offline, they happen to make an online version of this that you can easily try out right now. I’ve already populated it with the latest multiplication example (https://google.github.io/traceur-compiler/demo/repl.html#var%20multiply%...
(a%2C%20b)%20%3D%3E%20a%20*%20b%3B%0Aconsole.log(multiply(1%2C2))%3B). See your browsers console log for the output from the tool.