What destructuring is
Some values belong together: a pet's name and age, or the hours and minutes of a walk. JavaScript has no separate tuple type, so a small array holds the pair. You read a value by its index, and destructuring gives each value its own name in one line.
const pet = ["Rex", 4];
console.log(pet[0]); // Rex
const [name, age] = pet;
console.log(name + " is " + age);
This prints:
Rex
Rex is 4
The names go in square brackets on the left of the =, in the same order as the values. The first name gets the first value, the second name the second value, and so on.
The left side is not a new kind of array. It is a pattern that says which positions to name. You can also read a pair without destructuring, with pet[0] and pet[1]. That works, but the numbers say nothing about what they mean. In const [name, age] = pet, the names do the explaining, so the code that follows is easier to read.
Returning two values from a function
A function can return only one value, but that value can be an array of two. The caller destructures the result:
function firstAndLast(word) {
return [word[0], word[word.length - 1]];
}
const [first, last] = firstAndLast("code");
console.log(first + last); // ce
Watch the count
Destructuring does not complain when the numbers differ. A name with no matching value gets undefined, and extra values are ignored:
const pet = ["Rex", 4];
const [a, b, c] = pet;
console.log(c); // undefined
const [p, q] = [1, 2, 3];
console.log(p, q); // 1 2
If the right side is not an array (or something else iterable), destructuring throws. For example, destructuring the result of a function that forgot to return a value fails with TypeError: bad is not a function or its return value is not iterable. A related slip is writing the array as a bare expression without return: the function then gives back undefined.
The lesson's task, step by step
The exercise has three parts.
- Make
splitTimereturn a pair. The whole hours areMath.floor(minutes / 60)and the minutes left areminutes % 60. Return both in one array, hours first. - Destructure
pet. Writeconst [name, age] = pet;below the firstconsole.log. - Destructure the result of
splitTime(135)intohoursandmins. Since 135 minutes is 2 hours and 15 minutes, the pair is[2, 15].
The finished program:
function splitTime(minutes) {
return [Math.floor(minutes / 60), minutes % 60];
}
const pet = ["Rex", 4];
console.log(pet[0]);
const [name, age] = pet;
console.log(name + " is " + age);
const [hours, mins] = splitTime(135);
console.log(name + " walked " + hours + " h " + mins + " min");
Its output matches the expected output:
Rex
Rex is 4
Rex walked 2 h 15 min
Order matters in every step. Swapping the two names in const [hours, mins] would put the minutes in hours, and JavaScript would not warn you, because it only matches by position.
Swapping and looping
Destructuring is not limited to declarations. Assigning into existing variables swaps them without a helper:
let m = 1, n = 2;
[m, n] = [n, m];
console.log(m, n); // 2 1
The same pattern works in a for...of loop over an array of pairs, where each pair is unpacked as the loop reaches it:
const pets = [["Rex", 4], ["Bella", 7]];
for (const [name, age] of pets) {
console.log(name + " is " + age);
}
This prints Rex is 4 and then Bella is 7. Later lessons in this chapter use it.
Key takeaways
- A small array keeps a pair together;
pet[0]andpet[1]read the parts. const [name, age] = pet;names the parts in one line, in order.- To return two values, return an array of two and destructure it at the call.
- Too few values leave
undefined; too many are ignored. Count them. - Matching is by position, never by name, so keep the order the same on both sides.
