Learning ES6 - Default Values & Destructuring
6 min read.
Today, I thought that we could speak about two new features in ECMAScript 6 that are pretty useful when writing functions: default values and destructuring.
Default Values
If you forget to supply a parameter to a function in ECMAScript 5 and below, it would always default missing parameters to undefined.
function printWelcomeMessage(name) {
var message = 'Welcome ' + name + '!';
console.log(message);
}
printWelcomeMessage(); // => welcome undefined!
This meant that we had to test the incoming parameters at the beginning of the function to make sure that the values were not undefined.
function printWelcomeMessage(name) {
name = !!name ? name : 'John Doe';
var message = 'Welcome ' + name + '!';
console.log(message);
}
printWelcomeMessage(); // => welcome John Doe!
However, with ECMAScript 6 we don’t need to do these types of testing anymore. We can now simply supply a default value for the parameters in the in the function head instead, making the functions less cluttered.
Using the new way of assigning default values, then the example above would look something like the following:
function printWelcomeMessage(name = 'John Doe') {
var message = 'Welcome ' + name + '!';
console.log(message);
}
printWelcomeMessage(); // => welcome John Doe!
Pretty neat huh? Also, because the default value is evaluated at runtime, we can use any type of expression, like a function
:
const GENDER = 'female';
function getDefaultName(gender) {
if(gender === 'man') {
return 'John Doe';
} else {
return 'Jane Doe';
}
}
function printWelcomeMessage(name = getDefaultName(GENDER)) {
var message = 'Welcome ' + name + '!';
console.log(message);
}
printWelcomeMessage(); // => welcome Jane Doe!
That is pretty much everything you need to know about default values. Although the examples above only assign default values to function parameters, they can also be used in other cases, like for destructuring.
Destructuring
Destructuring is the new way to assign values or properties of an Array or Object to variables. In ECMAScript 5 you would write something like the following to this:
var nums = [1, 2, 3];
var one = nums[0];
var two = nums[1];
var three = nums[3];
Now, in ECMAScript 6 you can, with destructuring, condense this down to the following statement:
var nums = [1, 2, 3];
var [one, two, three] = nums;
console.log(one, two, three); // => 1 2 3
If we try to destructure a value that is not available we will get undefined
. These values can also be assigned default values, just like the parameters for the functions in the previous section:
let [noValue] = [];
console.log(noValue); // => undefined
let [noValue = 'default value'] = [];
console.log(noValue); // => default value.
As you can see, we can also use the new declarations let
and const
, which we talked about in the beginning of this series, to declare new variables when destructuring. Forgetting to declare the variables when destructuring will cause a SyntaxError
.
We can declare only the values we want as well, by using commas without values:
let [,,three] = [1,2,3]; // => three = 3.
let [,two,] = [1,2,3]; // => two = 2.
Destructuring can also be used for extracting values from nested Arrays:
let nestedArray = [ [1, 2], [3, 4], [5, 6] ];
let [ [a, b], [c, d], [e, f] ] = nestedArray;
console.log(a, b, c, d, e, f) => // 1 2 3 4 5 6
Objects
So far we have only looked at destructuring Arrays, but it is also possible to destructure Objects. The difference though, and it might not come as a surprise, is that we use curly brackets instead of regular brackets:
let user = {
name: { forename: 'John', surname: 'Smith' },
age: 40
};
let {{forename, surname}, age, job = 'cleaner'} = user;
console.log(forename, surname, age, job); // => John Smith 40 cleaner.
And just as with the Arrays, we will get a SyntaxError
if we forget to declare the variables. However, wrapping the Object destructuring in parentheses will let you destructure the object without declaring the variables:
{ name } = {name: 'Smith'}; // => SyntaxError.
({ name } = {name: 'Smith'}); // => is OK.
We can also rename the properties of the Object while destructuring them:
var {name: surname} = {name: 'Smith'};
console.log(surname); // => Smith.
Destructuring Arrays and Object is okay, but what is even better is that you can mix it up as well:
var mixedObject = {
first: 1,
array: [2, {third: 3}, 4]
};
var {first, [second, {third} , fourth]} = mixedObject;
console.log(first, second, third, fourth); // => 1 2 3 4.
Use Cases
A common way to minimize the number of parameters sent to functions is to supply an object instead of writing them all as parameters. An example of this is the settings
object you can pass to $.ajax
in jQuery.
As we do this, we get a smaller function head as argued before. However, we will also end up with more code in the function body. Either we get longer variable names because we need to read the value directly from the passed settings object:
function fetch(settings) {
get(settings.url, settings.data);
...
}
Or we have to declare each variable in the settings object before using it:
function fetch(settings) {
let url = settings.url;
let data = settings.data;
get(url, data);
}
By now, you probably see where I’m going with this. We could use destructuring to condense the function body down into less code and also make it more readable!
function fetch(settings) {
let {url, data} = settings;
get(url, data);
}
Short and easy to read. We could even supply a default settings object if one was not given using the default parameters we talked about in the beginning of this post:
const DEFAULT_SETTINGS = {url: '/', data: 'hello world!'};
function fetch(settings = DEFAULT_SETTINGS) {
let {url, data} = settings;
get(url, data);
}
With destructuring, we can also write functions that return multiple values. In reality, the function will return an Object or Array but with destructuring, we can handle them as separate values:
function getCoords() {
return {x: 1, y: 2, z:3}
}
var {x, y ,z} = getCoords();
When importing ECMAScript 6 modules, we can use destructuring to specify which parts of the modules we want to import. However, I will leave this for a future blog post, as it deserves one of its own.
Previous Posts
If you liked this post checkout some of the previous posts in this series: