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.
[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.
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 examples below.
This capability is similar to features present in languages such as Perl and Python.
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;
Destructuring assignment can be made without a declaration in the assignment statement.
var a, b; [a, b] = [1, 2];
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];
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.
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();
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:"
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
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 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 });
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 for destructured default values in functions.
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');
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"
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"
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 property names, like on object literals, can be used with destructuring.
let key = "z"; let { [key]: foo } = { z: "bar" }; console.log(foo); // "bar"
([a, b]) = [1, 2]
or ({a, b}) = { a: 1, b: 2 }
, are now considered invalid and will throw a SyntaxError. See Jeff Walden's blog post and for more details.Created by Mozilla Contributors, license: CC-BY-SA 2.5