Modern JavaScript: Basic Array Destructuring
Welcome to the Basic Array Destructuring lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Historically, working with arrays and objects in JavaScript was clunky. Suppose that we want to extract the first three elements of an array into separate variables:
>
const letters = ['a', 'b', 'c', 'd'];const a = letters[0], b = letters[1], c = letters[2];[a, b, c];Result:
['a', 'b', 'c']
This gets the job done, but it's cumbersome to read and write. Fortunately, modern JavaScript has a nicer way to do this. The next example does the exact same thing, but with modern syntax. Notice how much shorter the
[a, b, c]assignment is!>
const letters = ['a', 'b', 'c', 'd'];const [a, b, c] = letters;[a, b, c];Result:
['a', 'b', 'c']
This feature is called "destructuring". An array has some structure: certain values at certain indexes. We use destructuring syntax to unpack that structure and access the individual pieces. We "de-structure" the array.
Since we're declaring variables, we can name them anything we want.
Here's a code problem:
Use array destructuring to extract the first two user names in the list. Put them in the
firstUserandsecondUservariables.const names = ['Amir', 'Betty', 'Cindy', 'Dalili'];const [firstUser, secondUser] = names;const users = [firstUser, secondUser];users;- Goal:
['Amir', 'Betty']
- Yours:
['Amir', 'Betty']
Assignments with
let,const, and the legacyvarsyntax can all use destructuring.>
const letters = ['a', 'b', 'c', 'd'];let [a, b, c] = letters;[a, b, c];Result:
>
const letters = ['a', 'b', 'c', 'd'];var [a, b, c] = letters;[a, b, c];Result:
We can skip array indexes by leaving them out of the destructuring syntax entirely.
>
const letters = ['a', 'b', 'c', 'd'];const [a, , c] = letters;[a, c];Result:
['a', 'c']
Skipping indexes like this is called "sparse array destructuring". ("Sparse" means "thinly dispersed or scattered". We use "sparse" in many programming situations where a structure has empty spots.)
If we try to destructure a value that doesn't have structure, like
nullorundefined, we'll get an error. (You can typeerrorwhen a code example will throw an error.)>
const [a, b, c] = null;Result:
TypeError: null is not iterable
>
const [a, b, c] = 5;Result:
TypeError: 5 is not iterable
If the object has too few indexes and we try to destructure non-existent elements, we'll get
undefined, but no error occurs.>
const letters = ['a', 'b', 'c'];const [a, b, c, d] = letters;[c, d];Result:
['c', undefined]
To avoid the
undefineds we saw above, we can provide default values. If the array has no value at that key, we'll get the default instead. (Note the new=syntax in the destructuring below.)>
const letters = ['a', 'b', 'c'];const [a, b, c, d='dee'] = letters;[c, d];Result:
['c', 'dee']
>
const letters = ['a', 'b', 'c', 'd'];const [a, b, c, d='dee'] = letters;[c, d];Result:
['c', 'd']
Elements with and without defaults can be mixed. In the example below,
dhas a default butedoesn't. The matched array has no value fore, so it will get the valueundefined.>
const letters = ['a', 'b', 'c'];const [a, b, c, d='dee', e] = letters;[d, e];Result:
['dee', undefined]
We can collect any remaining elements using
..., similar to how we used "rest parameters" in function definitions. The...in the next example collects all of the array elements that weren't matched in the destructuring.>
const letters = ['a', 'b', 'c'];const [a, ...others] = letters;others;Result:
['b', 'c']
Rest parameters are always returned to us in an array, even if there's only a single rest parameter.
>
const letters = ['a', 'b', 'c'];const [a, b, ...others] = letters;others;Result:
['c']
Here's a code problem:
Use a single array destructuring operation to:
- Put the first and second user names into
firstUserandsecondUservariables. - Put the rest of the user names into an
otherUsersvariable.
const names = ['Amir', 'Betty', 'Cindy', 'Dalili'];const [firstUser, secondUser, ...otherUsers] = names;const users = [firstUser, secondUser, otherUsers];users;- Goal:
['Amir', 'Betty', ['Cindy', 'Dalili']]
- Yours:
['Amir', 'Betty', ['Cindy', 'Dalili']]
- Put the first and second user names into
What about destructuring with
[...others, c]? It seems like that should mean "put the last element incand all other elements before it inothers." However, that's not supported and will throw an error.>
const letters = ['a', 'b', 'c']const [...others, a] = lettersothersResult:
SyntaxError: on line 2: Rest element must be last element.
Strings can also be destructured in this way. When we destructure a string, we get the string's individual characters. JavaScript has no dedicated character type, so the characters will be represented as strings with length 1, like
'a'.>
const letters = 'abc';const [a, b, c] = letters;b;Result:
'b'
Rest parameters work with strings as well, giving us an array of the individual characters.
>
const s = 'xyz';const [...chars] = s;chars;Result:
['x', 'y', 'z']