Written on
Assignment Destructuring in JavaScript
A quick guide for array and object destructuring in JavaScript
In JavaScript, assignment destructuring is a way to assign one or more elements of an existing array or an object (positioned on the right) into one or more variables (positioned on the left).
let [a, b] = [1, 2];
console.log(a) // 1
console.log(b) // 2
Let's start by focusing on array destructuring. Let's use as an example a simple array containing numbers from 1 to 10.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Skipping Elements
By adding an empty space between commas, you skip one position in the array.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, , b] = array // a == 1, b == 3
Add more commas to skip more items
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, , , b] = array
// a == 1
// b == 4
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, , , , b] = array
// a == 1
// b == 5
Assigning More Elements than Existing Ones
If you assign more elements than the number of elements present in the source, the remaining element are undefined
.
array = [1, 2, 3, 4, 5];
[a, b, c, d, e, f] = array
console.log(f) // undefined
The Rest Property
To transfer more than one item in an array into a single variable, you can use the rest property (...
).
The rest property enumerates all of the items in an array and puts them in a separate array.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [...a] = array;
// a == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
You can combine the rest property together with the commas. You can use it to assign individual items from an array.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, b, ...rest] = array
// a == 1
// b == 2
// rest == [3, 4, 5, 6, 7, 8, 9, 10]
Commas also allow you to skip items in an array, affecting the items the rest property interacts with.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, , b, ...rest] = array
// a == 1
// b == 3
// rest == [3, 4, 5, 6, 7, 8, 9, 10]
If you want to use the rest property to destructure individual items instead of positioning them in an array, just add square brackets.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[a, b, ...[c, d]] = array
// a == 1
// b == 2
// c == 3
// d == 4
You can also use the rest property to access arrays properties, although the properties are from the already modified array, not the original one.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[a, b, ...{ length }] = array
console.log(length) // 8
Position of Rest Property
Remember that the rest property always needs to be at the end of the destructured array.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const [a, ...b , c] = array;
//Uncaught SyntaxError: Rest element must be last element
If you use the Rest property in a nested way, the first nested property still needs to be the last element of the object.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let [a, b, ...[c, d, , ...[e]]] = array
console.log(a, b, c, d, e) // 1 2 3 4 6
Object Destructuring
So far, we only saw examples of array destructuring in arrays, but you can use assignment destructuring also for objects.
Let's see how assignment destructuring works in JavaScript by looking at this sample object.
const obj = { name: "John", surname: "Smith", age: 25}
Parenthesis Wrapping
When attempting to do object destructuring, you'll notice that a SyntaxError in the browser console:
const obj = {firstName: "John", lastName: "Smith", age: 25};
{firstName, lastName} = obj; // SyntaxError: Unexpected token '='
console.log(firstName, lastName);
To avoid this error, wrap the entire object destructuring assignment in parentheses...
const obj = {firstName: "John", lastName: "Smith", age: 25};
({firstName, lastName} = obj);
console.log(firstName, lastName); // "John Smith"
...or you can declare the object destructuring assignment as a variable.
const obj = {firstName: "John", lastName: "Smith", age: 25};
let {firstName, lastName} = obj;
console.log(firstName, lastName);
// "John Smith"
Key Assignment
If I try to assign the information associated to the keys name
, surname
, age
to variables named in a different way (for example, a
, b
, c
) these variables return undefined as a value.
const obj = { name: "John", surname: "Smith", age: 25}
const ({ a, b, c } = obj)
console.log(a) // undefined
console.log(b) // undefined
console.log(c) // undefined
However, if I assign these key values to the variables named after the keys, I get the correct assignment.
const obj = { name: "John", surname: "Smith", age: 25}
const { name, surname, age } = obj
console.log(name) // "John"
console.log(surname) // "Smith"
console.log(age) // 25
If I include keys in the object to the left, I can assign key values to variables with different names.
const obj = { name: "John", surname: "Smith", age: 25}
const { name: a, surname: b, age: c } = obj
console.log(a) // "John"
console.log(b) // "Smith"
console.log(c) // 25
Object Destructuring and the Rest Property
You can use the rest property (...
) also while destructuring an object. The result will be a new object.
const obj = {
name: "John",
surname: "Smith",
age: 25
}
const { name, ...rest } = obj
console.log(name)
// "John"
console.log(rest)
// { surname: 'Smith', age: 25 }
The rest property works in the same way even if you use an object with keys on the left.
const obj = {
name: "John",
surname: "Smith",
age: 25
}
const { name: a, ...rest } = obj
console.log(a)
// "John"
console.log(rest)
// { surname: 'Smith', age: 25 }
However, when working with an object, you can use the rest property only with one variable.
const obj = {
name: "John",
surname: "Smith",
age: 25
}
({name, ...{surname, age} } = obj)
// SyntaxError: `...` must be followed by an assignable
// reference in assignment contexts
const obj = {
name: "John",
surname: "Smith",
age: 25
}
({name: a, ...{surname: b, age: c} } = obj)
// SyntaxError: `...` must be followed
// by an assignable reference in assignment contexts
Destructuring Nested Objects
To destructure nested objects, remember to replicate the original object structure accurately.
const player = {
firstName: "Alessandro",
lastName: "Del Piero",
teams: {
club: "Juventus",
national: "Italy"
}
}
const {
firstName,
lastName,
teams: {club, national}
} = player
console.log(firstName, lastName, club, national)
// Alessandro Del Piero Juventus Italy
Cannot Destructure Object into Arrays
Since array destructuring uses iteration, you cannot destructure an object (which is non-iterable) into an array (which is iterable).
const obj = {
name: "John",
surname: "Smith",
age: 25
}
[d, e, f] = obj
// Uncaught TypeError: object is not iterable
// (cannot read property Symbol(Symbol.iterator))
Constants and Variables in Assignment Destructuring
In the examples we saw so far, we used only the const
declaration to destructure assignments. Of course, you can use also let
, based on your needs.
Moreover, you can also declare specific parts of an array or object in different ways, so that you can fine-tune what you want to keep and what you may want to change later on.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const [a] = array;
let b;
[, b] = array;
console.log(a, b); // 1, 2
b = "two";
console.log(a, b); // 1, "two"
Assignment Patterns
All the previous examples dealt with binding examples, meaning that we are destructuring arrays or objects we already declared. However, we can also assign data to an empty array.
const array = []
const obj = {
name: "John",
surname: "Smith",
age: 25
}
({firstName: array[0], lastName: array[1], age: array[2]} = obj)
console.log(array)
// [ 'John', 'Smith', 25 ]
Default Values
You can assign default values to destructured properties, which replaces empty or undefined
items.
const array = [, 2, 3, 4, 5, 6, 7, 8, 9, 10];
[a = 1, ...rest] = array;
console.log(a) // 1
const array = [undefined, 2, 3, 4, 5, 6, 7, 8, 9, 10];
[a = 1, ...rest] = array;
console.log(a) // 1
If the item is null
, the default value does not work.
const array = [null, 2, 3, 4, 5, 6, 7, 8, 9, 10];
[a = 1, ...rest] = array;
console.log(a) // null
Default values also work in objects.
const obj = {
name: "John",
surname: "Smith",
age: 25
}
let { name, surname, age = 18, city = "New York" } = obj
console.log(name, surname, age, city)
// John Smith 25 New York
Common Uses of Destructuring Assignments
Assignment Destructuring and Functions
The returned values of a function can be part of a destructuring assignment.
function helloWorld() {
return ["Hello", "World"]
}
const [a, b] = helloWorld();
console.log(a, b); // "Hello World"
You can use assignment destructuring to get a specific value of an object. This function takes as a parameter the value associated to the key "age" of the provided object
const obj = {
name: "John",
surname: "Smith",
age: 25
}
function getAge({ age }) {
return age
}
getAge(obj) // 25
You can also rename the parameter. This function takes as a parameter the value associated to the key "age" of the provided object.
const obj = {
name: "John",
surname: "Smith",
age: 25
}
function getAge({ age: years }) {
return years
}
getAge(obj) // 25
You can also access nested keys in an object.
const player = {
firstName: "Alessandro",
lastName: "Del Piero",
teams: {
club: "Juventus",
national: "Italy"
}
}
function getTeams(
{lastName, teams: {club, national}}
) {
return `${lastName} played for ${club} and ${national}`
}
getTeams(player)
// 'Del Piero played for Juventus and Italy'
As usual, you can also assign default values.
const player2 = {
lastName: "Ronaldo",
teams: {
club: "Real Madrid",
national: "Portugal"
}
}
function getTeams(
{
firstName = "Cristiano",
lastName,
teams: {club, national}
}) {
return `${firstName} ${lastName} played for ${club} and ${national}`
}
getTeams(player2)
// Cristiano Ronaldo played for Real Madrid and Portugal
Swapping Variables
Assignment destructuring is useful for swapping variables.
let a = "Hello";
let b = "World";
[a, b] = [b, a];
console.log(a, b)
// "World Hello"
Assignment destructuring is also an excellent way to shuffle an array, as explained in JavaScript.info (spoilers for exercises!)
export function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
Assignment Destructuring and Loops
You can also use assignment destructuring together with for ... in
loops.
const players = [
{ firstName: "Alessandro", lastName: "Del Piero", teams: { club: "Juventus", national: "Italy" }},
{ firstName: "Cristiano", lastName: "Ronaldo", teams: { club: "Real Madrid", national: "Portugal" }}
];
for (const {lastName: surname, teams: { club: c, national: n }} of players) {
console.log(`${surname} played for ${c} and ${n}`)
// Del Piero played for Juventus and Italy
// Ronaldo played for Real Madrid and Portugal
}
Combining Arrays and Objects in Assignment Destructuring
You can easily combine array and object destructuring.
You can destructure objects inside an array. For example here I'm assigning the value associated to the key "lastName" in the second item of the array "players".
const players = [
player1 = { firstName: "Alessandro", lastName: "Del Piero", teams: { club: "Juventus", national: "Italy" }},
player2 = { firstName: "Cristiano", lastName: "Ronaldo", teams: { club: "Real Madrid", national: "Portugal" }}
];
[ , {lastName} ] = players //
console.log(lastName) // Ronaldo
You can also destructure arrays inside objects, as in the example below.
const player = { firstName: "Roberto", lastName: "Baggio", clubs: ["Vicenza", "Fiorentina", "Juventus", "Milan", "Inter", "Bologna", "Brescia"]}
{ clubs: [ , , club, ...rest] } = player
console.log(club, rest)
// Juventus [ 'Milan', 'Inter', 'Bologna', 'Brescia' ]
I hope you enjoyed the reading!