JavaScript - destructuring assignment

revision:


Content

The destructuring assignment syntax in JavaScript. Array destructuring Object destructuring Nested destructuring Some more destructuring examples


The destructuring assignment syntax in JavaScript.

top

This syntax is an expression that makes it possible to "unpack values" from arrays, or "unpack properties" from objects, into distinct variables.

It's called "destructuring assignment", because it "destructurizes" by copying items into variables. But the array itself is not modified.

Syntax

The basic syntax of array destructuring: let [identifier, identifier, ... ] = arrary;

The basic syntax of object destructuring: let { var1, var2 } = {var1:..., var2:...};

where "identifier" is the name of the property to access and "expression" should evaluate to an object;
after the destructuring, the variable identifier contains the property value.

To destructure the object into multiple properties, enumerate as many properties as you like adding commas ( , ) in-between: const { identifier1, identifier2, ..., identifierN } = expression;

Syntax examples

            const [a, b] = array;
            const [a, , b] = array;
            const [a = aDefault, b] = array;
            const [a, b, ...rest] = array;
            const [a, , b, ...rest] = array;
            const [a, b, ...{ pop, push }] = array;
            const [a, b, ...[c, d]] = array;

            const { a, b } = obj;
            const { a: a1, b: b1 } = obj;
            const { a: a1 = aDefault, b = bDefault } = obj;
            const { a, b, ...rest } = obj;
            const { a: a1, b: b1, ...rest } = obj;

            let a, b, a1, b1, c, d, rest, pop, push;
            [a, b] = array;
            [a, , b] = array;
            [a = aDefault, b] = array;
            [a, b, ...rest] = array;
            [a, , b, ...rest] = array;
            [a, b, ...{ pop, push }] = array;
            [a, b, ...[c, d]] = array;

            ({ a, b } = obj); // brackets are required
            ({ a: a1, b: b1 } = obj);
            ({ a: a1 = aDefault, b = bDefault } = obj);
            ({ a, b, ...rest } = obj);
            ({ a: a1, b: b1, ...rest } = obj);
        

Array destructuring

top

An example of an array destructured into variables

example

code:
                    <div>
                        <p class="spec" id="des-01"></p>
                        <p class="spec" id="des-02"></p>
                        <p class="spec" id="des-03"></p>
                    </div>
                    <script>
                        let arr = ["John", "Smith"]
                        document.getElementById("des-01").innerHTML = "original array: " + arr;
                        // destructuring assignment sets firstName = arr[0] and surName = arr[1]
                        let [firstName, surName] = arr;
                        document.getElementById("des-02").innerHTML = "firstName: " + firstName; 
                        document.getElementById("des-03").innerHTML = "surName:  " + surName; 
                   </script>
                

Array destructuring allows to work with variables instead of array members. The syntax is simple, but there are several peculiar details though.

Unwanted elements of the array can be thrown away via an extra comma.

code
                // second element is not needed
                let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
                alert( title ); // Consul
            

Works with any iterable on the right-side. Actually, we can use it with any iterable, not only arrays, because internally a destructuring assignment works by iterating over the right value. It's kind of syntax sugar for calling "for..of" over the value to the right of "=" and assigning the values.

code:
                let [a, b, c] = "abc"; // ["a", "b", "c"]
                let [one, two, three] = new Set([1, 2, 3]);
            

Assign to anything at the left-side. Any "assignables" at the left side can be used. For instance, an object property.

code:
                let user = {};
                [user.name, user.surname] = "John Smith".split(' ');
              
                alert(user.name); // John
                alert(user.surname); // Smith
            

Looping with .entries(). The Object.entries(obj) method can be used with destructuring to loop over keys-and-values of an object.

code:
                let user = {
                    name: "John",
                    age: 30
                  };
                  
                  // loop over keys-and-values
                  for (let [key, value] of Object.entries(user)) {
                    alert(`${key}:${value}`); // name:John, then age:30
                  }
            

Swap variables trick: there's a well-known trick for swapping values of two variables using a destructuring assignment.

code:
                let guest = "Jane";
                let admin = "Pete";
                // Let's swap the values: make guest=Pete, admin=Jane
                [guest, admin] = [admin, guest];
                alert(`${guest} ${admin}`); // Pete Jane (successfully swapped!)
               
            

The rest '…' : usually, if the array is longer than the list at the left, the "extra" items are omitted. If we'd like also to gather all that follows – we can add one more parameter that gets "the rest" using three dots "...".

For example, here only two items are taken, and the rest is just ignored

code:
                let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
                alert(name1); // Julius
                alert(name2); // Caesar
                // Further items aren't assigned anywhere
               
            

The value of "rest" is the array of the remaining array elements.

code:
                let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
                // rest is array of items, starting from the 3rd one
                alert(rest[0]); // Consul
                alert(rest[1]); // of the Roman Republic
                alert(rest.length); // 2
               
            

We can use any other variable name instead of "rest", just make sure it has three dots before it and goes last in the destructuring assignment.

code:
                let [name1, name2, ...titles] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
                // now titles = ["Consul", "of the Roman Republic"]
               
            

Default values: if the array is shorter than the list of variables at the left, there'll be no errors.

Absent values are considered undefined.

code:
                let [firstName, surname] = [];
                alert(firstName); // undefined
                alert(surname); // undefined
            

If we want a "default" value to replace the missing one, we can provide it using "=".

code:
                // default values
                let [name = "Guest", surname = "Anonymous"] = ["Julius"];
                alert(name);    // Julius (from array)
                alert(surname); // Anonymous (default used)
            

Object destructuring

top

The basic syntax is: let {var1, var2} = {var1:…, var2:…}.

We should have an existing object at the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in {...}.

Properties "options.title", "options.width" and "options.height" are assigned to the corresponding variables.

code
                let options = {
                    title: "Menu",
                    width: 100,
                    height: 200
                  };
                  
                  let {title, width, height} = options;
                  
                  alert(title);  // Menu
                  alert(width);  // 100
                  alert(height); // 200
            

The order does not matter. This works too:

code:
                // changed the order in let {...}
                let {height, width, title} = { title: "Menu", height: 200, width: 100 }
            

If we want to assign a property to a variable with another name, - for instance, make options.width go into the variable named w, - then we can set the variable name using a colon.

code:
                let options = {
                    title: "Menu",
                    width: 100,
                    height: 200
                };
                // { sourceProperty: targetVariable }
                let {width: w, height: h, title} = options;
                // width -> w
                // height -> h
                // title -> title
                alert(title);  // Menu
                alert(w);      // 100
                alert(h);      // 200
            

If we have a complex object with many properties, we can extract only what we need:

code:
                let options = {
                    title: "Menu",
                    width: 100,
                    height: 200
                  };
                // only extract title as a variable
                  let { title } = options;
                  alert(title); // Menu
            

The rest pattern "…" can be used if the object has more properties than variables.

code:
                let options = {
                    title: "Menu",
                    height: 200,
                    width: 100
                };
                // title = property named title
                // rest = object with the rest of properties
                let {title, ...rest} = options;
                // now title="Menu", rest={height: 200, width: 100}
                alert(rest.height);  // 200
                alert(rest.width);   // 100
            

Nested destructuring

top

If an object or an array contain other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.

In the code on the right, options has another object in the property size and an array in the property items. The pattern at the left side of the assignment has the same structure to extract values from them:

code:
                    let options = {
                        size: {
                          width: 100,
                          height: 200
                        },
                        items: ["Cake", "Donut"],
                        extra: true
                    };
                    // destructuring assignment split in multiple lines for clarity
                    let {
                        size: { // put size here
                          width,
                          height
                        },
                        items: [item1, item2], // assign items here
                        title = "Menu" // not present in the object (default value is used)
                    } = options;
                      
                    alert(title);  // Menu
                    alert(width);  // 100
                    alert(height); // 200
                    alert(item1);  // Cake
                    alert(item2);  // Donut
                

Some more destructuring examples

top
example: basic array destructuring.

code:
                    <script>
                        let introduction = ["Hello", "I" , "am", "Louis"];
                        document.getElementById("des-05").innerHTML = "original array: " + introduction;
                        let [greeting, pronoun] = introduction;
                        console.log(greeting);
                        console.log(pronoun);
                        document.getElementById("des-06").innerHTML = greeting;
                        document.getElementById("des-07").innerHTML = pronoun;
            
                        let [greeting1, pronoun1] = ["Hello", "I" , "am", "Louis"];
                        document.getElementById("des-08").innerHTML = "original array: " + [greeting1, pronoun1];
                        console.log(greeting);//"Hello"
                        console.log(pronoun);//"I"
                        document.getElementById("des-09").innerHTML = greeting1;
                        document.getElementById("des-10").innerHTML = pronoun1;
                    </script>
                

example: basic object destructuring.

code:
                    <script>
                        let person = {name: "Louis", country: "Belgium", job: "innovator"};
                        document.getElementById("des-11").innerHTML = `${person.name} lives in ${person.country} and is an ${person.job}.`; 
                        let {name, country, job} = person;
                        console.log(name);
                        console.log(country);
                        console.log(job);
                        document.getElementById("des-12").innerHTML = name;
                        document.getElementById("des-13").innerHTML = country;
                        document.getElementById("des-14").innerHTML = job;
            
                        let {name1, country1, job1} = {name1: "Louis", country1: "Belgium", job1: "innovator"};
                        console.log(name1);
                        console.log(country1);
                        console.log(job1);
                        document.getElementById("des-15").innerHTML = name1;
                        document.getElementById("des-16").innerHTML = country1;
                        document.getElementById("des-17").innerHTML = job1;
                    </script>