Background
The syntax for destructuring objects was added to the ECMAScript Language Specification starting from ES2015 (popularly known as ES6). This syntax makes it possible to break down complex JavaScript values like objects into simpler parts that can be assigned to local variables.
The destructuring syntax comes in two basic flavors:
- Array destructuring
// Array Destructuring
// Skip the first item (red)
// Setting a default for the third item (blue)
const [, green, blue = 51] = [255, 180];
console.log(green); // 180
console.log(blue); // 51
- Object destructuring
// Object Destructuring
// Declaring a language local variable for `lang`
// Setting a default for age
const {name, lang: language, age = 16} = {
name: 'Glad Chinda',
lang: 'JavaScript'
};
console.log(lang); // undefined
console.log(language); // "JavaScript"
console.log(age); // 16
However, it is possible to have destructuring syntax that is a mix of both flavors, nested in a certain way.
In this post, we will focus on destructuring for arrays. If you are not already familiar with the destructuring syntax, you can check out this guide to learn more.
Array Destructuring
The array destructuring syntax has proven useful for quite a lot of applications. A very common application of array destructuring is in swapping variables.
Without the array destructuring syntax, swapping the values of two variables will always require a third temporary variable. With array destructuring, that is not the case.
let width = 1280;
let height = 720;
// Without Array Destructuring
let temp = width;
width = height;
height = temp;
// With Array Destructuring
[width, height] = [height, width];
Another very common use of the array destructuring syntax is in combination with the rest parameters syntax for cloning arrays.
const scores = [23, 27, 22, 41, 35];
// Clone the `scores` array
const [...scoresClone] = scores;
console.log(scoresClone); // [23, 27, 22, 41, 35]
console.log(scores === scoresClone); // false
Also, array destructuring isn't limited to arrays alone (as the name implies), rather it can be used with iterables of all kinds such as strings, sets, array-likes like arguments
, etc.
// Array Destructuring with String
const [firstChar, ...otherChars] = 'Hello';
// Array Destructuring with Set
const [,, thirdItem] = new Set([1, 2, 3, 4, 5]);
console.log(firstChar); // "H"
console.log(otherChars); // ["e", "l", "l", "o"]
console.log(thirdItem); // 3
Limitations of Array Destructuring
Let's say we have an array ITEMS
of 100 items and we want to assign the last item to a variable named lastItem
. Basically, this can be done as follows:
// The 100th item is at index 99
const lastItem = ITEMS[99];
Trying to do this assignment using the array destructuring syntax doesn't make any sense, because it literally means you will have to skip the first 99 items (using commas) just to get to the last item.
It even gets worse when the number of items in the array is not known beforehand.
// Number of items not known
const lastItem = ITEMS[ITEMS.length - 1];
One might think for a moment here, that array destructuring can again be combined with the rest parameters syntax to solve this problem like so:
// Throws `SyntaxError`
// Rest element must always be the last element
const [...otherItems, lastItem] = ITEMS;
The above approach fails with a SyntaxError
due to the limitations placed on rest parameters:
- You can only have one rest parameters element.
- The rest parameters element, when present, must be the last element.
Can we try a different approach?
The answer is YES. Fundamentally, JavaScript arrays are objects (with special behaviors), and as such, can be targets for object destructuring.
Object Destructuring to the Rescue
According to the ECMAScript Language Specification, an array object is an exotic object that gives special treatment to array index property keys.
Hence, the following destructuring statements are equivalent:
// Array Destructuring
const [red, green, blue] = [255, 180, 51];
// Object Destructuring (equivalent)
const {0: red, 1: green, 2: blue} = [255, 180, 51];
That said, we can get the 100th item of the ITEMS
array from our previous example, and assign it to the lastItem
variable like so:
// Using object destructuring
// The 100th item is at index 99
const {99: lastItem} = ITEMS;
Using the object destructuring syntax makes it possible to introduce computed property names. For example, we can get the first, middle and last items of that ITEMS
array as follows:
// Using object destructuring
// Get the first, middle and last items
const {
0: firstItem,
[Math.floor(ITEMS.length / 2)]: midItem,
[ITEMS.length - 1]: lastItem
} = ITEMS;
Using the object destructuring syntax still allows us to assign values of named properties such as length
as long as they are enumerable.
That said, we can modify the previous code snippet, introducing the length
property like so:
// Using object destructuring
// Get the first, middle and last items
const {
length: len,
0: firstItem,
[Math.floor(len / 2)]: midItem,
[len - 1]: lastItem
} = ITEMS;
Finally, this approach, besides arrays, works for strings and other array-like objects (with special behaviors for index properties) as well.
const STRING = 'Hello World!';
const {length, [length - 1]: lastChar} = STRING;
console.log(length); // 12
console.log(lastChar); // "!"
Further Reading
- ES6 Destructuring: The Complete Guide
- Destructuring assignment
- ES6 In Depth: Destructuring
- Destructuring assignment
❤️ Like and Share
If you found this post insightful in any way, please:
- Like this post
- Comment your feedback
- Share with someone
- Follow me on Twitter
Top comments (0)