With normal assignment, you extract one piece of data at a time. For example, via:
With destructuring, you can extract multiple pieces of data at the same time, via patterns in locations that receive data. The left-hand side of
= in the previous code is one such location. In the following code, the square brackets in line A are a destructuring pattern. It extracts the values of the Array elements at index 0 and index 1:
Note that the pattern is “smaller” than the data: we are only extracting what we need.
Constructing data looks as follows:
Extracting data looks as follows:
So far, we haven’t seen a way to extract multiple values. Destructuring allows us to do that, via destructuring patterns. Syntactically, such patterns look similar to multi-value construction, but they appear where data is received (e.g. at the left-hand sides of assignments), not where data is created (e.g. at the right-hand sides of assignments).
const in line A declared and initialized the two variables
Destructuring patterns can be used at “assignment locations” such as:
Note that variable declarations include
let declarations in
Next, we’ll look deeper into the two kinds of destructuring: object-destructuring and Array-destructuring.
Object-destructuring lets you batch-extract values of properties, via patterns that look like object literals:
You can think of the pattern as a transparent sheet that you place over the data: The pattern key
'street' has a match in the data. Therefore, the data value
'Evergreen Terrace' is assigned to the pattern variable
You can also object-destructure primitive values:
And you can object-destructure Arrays (remember that Array indices are also properties):
Object literals support property value shorthands and so do object patterns:
In object literals, you can have spread properties. In object patterns, you can have rest properties (which must come last):
A rest property variable, such as
remaining (line A), is assigned an object with all data properties whose keys are not mentioned in the pattern.
We need to delay parsing via eval(), otherwise we already get an exception when this code is parsed.
assert.throws() only works if an exception is thrown inside the body of its function.
The work-around is to put the whole assignment in parentheses:
Array-destructuring lets you batch-extract values of Array elements, via patterns that look like Array literals:
You can skip elements by mentioning holes inside Array patterns:
The first element of the Array pattern in line A is a hole, which is why the Array element at index 0 is ignored.
Array-destructuring is useful when operations return Arrays. As does, for example, the regular expression method
You can also use destructuring to swap the values of two variables, without needing a temporary variable:
In Array literals, you can have spread elements. In Array patterns, you can have rest elements (which must come last):
A rest element variable such as
remaining (line A), is assigned an Array with all elements of the destructured value that were not mentioned, yet.
Array-destructuring can be applied to any value that is iterable, not just to Arrays:
Destructuring is very useful if a function returns multiple values – either packaged as an Array or packaged as an object.
Consider a function
findElement() that finds elements in an Array: Its parameter is a function that receives the value and index of an element and returns a boolean indicating if this is the element the caller is looking for. We are now faced with a dilemma: Should
findElement() return the value of the element it found or the index? One solution would be to create two separate functions, but that would result in duplicated code, because both functions would be very similar.
The following implementation avoids duplication by returning an object that contains both index and value of the element that is found:
Destructuring helps us with processing the result of
As we are working with property keys, the order in which we mention
index doesn’t matter:
The kicker is that destructuring also serves us well if we are only interested in one of the two results:
All of these conveniences combined make this way of handling multiple return values quite versatile.
What happens if there is no match for part of a pattern? The same thing that happens if you use non-batch operators: you get
If a property in an object pattern has no match on the right-hand side, you get
If an element in an Array pattern has no match on the right-hand side, you get
Object-destructuring only fails if the value to be destructured is either
null. That is, it fails whenever accessing a property via the dot operator would fail, too.
Array-destructuring demands that the destructured value be iterable. Therefore, you can’t Array-destructure
null. But you can’t Array-destructure non-iterable objects, either:
See quiz app.
All of the remaining sections are advanced.
Normally, if a pattern has no match, the corresponding variable is set to
With default values, you can specify a value other than
undefined, that should be used in such a case:
In line A, we specify the default value for
p to be
123. That default is used, because the data that we are destructuring has no property named
Here, we have two default values that are assigned to the variables
y, because the corresponding elements don’t exist in the Array that is destructured.
The default value for the first element of the Array pattern is
1, the default value for the second element is
You can also specify default values for object-destructuring:
Neither property key
first nor property key
last exist in the object that is destructured. Therefore, the default values are used.
With property value shorthands, this code becomes simpler:
Considering what we have learned in this chapter, parameter definitions have much in common with an Array pattern (rest elements, default values, etc.). In fact, the following two function declarations are equivalent:
Until now, we have only used variables as assignment targets inside destructuring patterns. But you can also use patterns as assignment targets, which enables you to nest patterns to arbitrary depths:
Inside the Array pattern in line A, there is a nested object pattern, at index 1.
See quiz app.