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.