mozilla
Your Search Results

    Destructuring assignment

    This is an experimental technology, part of the ECMAScript 6 (Harmony) proposal.
    Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

    The destructuring assignment syntax is a JavaScript expression that makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.

    Syntax

    [a, b] = [1, 2]
    [a, b, ...rest] = [1, 2, 3, 4, 5]
    {a, b} = {a:1, b:2}
    {a, b, ...rest} = {a:1, b:2, c:3, d:4}  //ES7
    

    {a, b} = {a:1, b:2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal.

    However, the ({a, b} = {a:1, b:2}) form is valid, as is the var {a, b} = {a:1, b:2} form.

    Description

    The object and array literal expressions provide an easy way to create ad hoc packages of data. Once you've created these packages of data, you can use them any way you want to. You can even return them from functions.

    One particularly useful thing you can do with destructuring assignment is to read an entire structure in a single statement, although there are a number of interesting things you can do with them, as shown in the section full of examples that follows.

    This capability is similar to features present in languages such as Perl and Python.

    Array destructuring

    Simple example

    var foo = ["one", "two", "three"];
    
    // without destructuring
    var one   = foo[0];
    var two   = foo[1];
    var three = foo[2];
    
    // with destructuring
    var [one, two, three] = foo;

    Assignment without declaration

    Destructuring assignment can be made without a declaration in the assignment statement.

    var a, b;
    
    [a, b] = [1, 2];

    Swapping variables

    After executing this code, b is 1 and a is 3. Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the XOR-swap trick).

    var a = 1;
    var b = 3;
    
    [a, b] = [b, a];

    Multiple-value returns

    Thanks to destructuring assignment, functions can return multiple values. While it's always been possible to return an array from a function, this provides an added degree of flexibility.

    function f() {
      return [1, 2];
    }
    

    As you can see, returning results is done using an array-like notation, with all the values to return enclosed in brackets. You can return any number of results in this way. In this example, f() returns the values [1, 2] as its output.

    var a, b;
    [a, b] = f();
    console.log("A is " + a + " B is " + b);
    

    The statement [a, b] = f() assigns the results of the function to the variables in brackets, in order: a is set to 1 and b is set to 2.

    You can also retrieve the return values as an array:

    var a = f();
    console.log("A is " + a);
    

    In this case, a is an array containing the values 1 and 2.

    Ignoring some returned values

    You can also ignore return values that you're not interested in:

    function f() {
      return [1, 2, 3];
    }
    
    var [a, , b] = f();
    console.log("A is " + a + " B is " + b);
    

    After running this code, a is 1 and b is 3. The value 2 is ignored. You can ignore any (or all) returned values this way. For example:

    [,,] = f();
    

    Pulling values from a regular expression match

    When the regular expression exec() method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to pull the parts out of this array easily, ignoring the full match if it is not needed.

    var url = "https://developer.mozilla.org/en-US/Web/JavaScript";
    
    var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
    var [, protocol, fullhost, fullpath] = parsedURL;
    
    console.log(protocol); // logs "https:"
    

    Object destructuring

    Simple example

    var o = {p: 42, q: true};
    var {p, q} = o;
    
    console.log(p); // 42
    console.log(q); // true 
    
    // Assign new variable names
    var {p: foo, q: bar} = o;
    
    console.log(foo); // 42
    console.log(bar); // true  

    Assignment without declaration

    Destructuring assignment can be made without a declaration in the assignment statement.

    var a, b;
    
    ({a, b} = {a:1, b:2});

    The ( .. ) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

    Function argument defaults

    ES5 version

    function drawES5Chart(options) {
      options = options === undefined ? {} : options;
      var size = options.size === undefined ? 'big' : options.size;
      var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
      var radius = options.radius === undefined ? 25 : options.radius;
      console.log(size, cords, radius);
      // now finally do some chart drawing
    }
    
    drawES5Chart({
      cords: { x: 18, y: 30 },
      radius: 30
    });

    ES6 version

    function drawES6Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) 
    {
      console.log(size, cords, radius);
      // do some chart drawing
    }
    
    drawES6Chart({
      cords: { x: 18, y: 30 },
      radius: 30
    });

    In Firefox, default values for destructuring assignments are not yet implemented: var { x = 3 } = {} and var [foo = "bar"] = []. See bug 932080 and also bug 1018628 for destructured default values in functions.

    Module (non-ES6) loading

    Destructuring can help to load specific subsets of a non-ES6 module like here in the Add-on SDK:

    const { Loader, main } = require('toolkit/loader');
    

    Nested object and array destructuring

    var metadata = {
        title: "Scratchpad",
        translations: [
           {
            locale: "de",
            localization_tags: [ ],
            last_edit: "2014-04-14T08:43:37",
            url: "/de/docs/Tools/Scratchpad",
            title: "JavaScript-Umgebung"
           }
        ],
        url: "/en-US/docs/Tools/Scratchpad"
    };
    
    var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
    
    console.log(englishTitle); // "Scratchpad"
    console.log(localeTitle);  // "JavaScript-Umgebung"

    For of iteration and destructuring

    var people = [
      {
        name: "Mike Smith",
        family: {
          mother: "Jane Smith",
          father: "Harry Smith",
          sister: "Samantha Smith"
        },
        age: 35
      },
      {
        name: "Tom Jones",
        family: {
          mother: "Norah Jones",
          father: "Richard Jones",
          brother: "Howard Jones"
        },
        age: 25
      }
    ];
    
    for (var {name: n, family: { father: f } } of people) {
      console.log("Name: " + n + ", Father: " + f);
    }
    
    // "Name: Mike Smith, Father: Harry Smith"
    // "Name: Tom Jones, Father: Richard Jones"

    Pulling fields from objects passed as function parameter

    function userId({id}) {
      return id;
    }
    
    function whois({displayName: displayName, fullName: {firstName: name}}){
      console.log(displayName + " is " + name);
    }
    
    var user = { 
      id: 42, 
      displayName: "jdoe",
      fullName: { 
          firstName: "John",
          lastName: "Doe"
      }
    };
    
    console.log("userId: " + userId(user)); // "userId: 42"
    whois(user); // "jdoe is John"

    This pulls the id, displayName and firstName from the user object and prints them.

    Computed object property names and destructuring

    Computed property names, like on object literals, can be used with destructuring.

    let key = "z";
    let { [key]: foo } = { z: "bar" };
    
    console.log(foo); // "bar"
    

    Specifications

    Specification Status Comment
    ECMAScript 6 (ECMA-262)
    The definition of 'Destructuring assignment' in that specification.
    Release Candidate Initial definition.

    Browser compatibility

    Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
    Basic support Not supported 2.0 (1.8.1) Not supported Not supported 7.1
    Computed property names Not supported 34 (34) Not supported Not supported Not supported
    Spread operator ? 34 (34) ? ? ?
    Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
    Basic support Not supported Not supported 1.0 (1.0) Not supported Not supported iOS 8
    Computed property names Not supported Not supported 34.0 (34) Not supported Not supported Not supported
    Spread operator ? ? 34.0 (34) ? ? ?

    Firefox-specific notes

    • Firefox provided a non-standard language extension in JS1.7 for destructuring. This extension has been removed in Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37). See bug 1083498.

    See also

    Document Tags and Contributors

    Last updated by: getify,
    Hide Sidebar