In a programming language, destructuring assignment denotes the use of patterns to extract parts of an object. If we refer to Common LISP, destructuring assignment binds a set of variables to a corresponding set of values, where normally bind a value to a single variable. For the next-generation ECMAScript 6, destructuring feature is slated to be an important addition to the assignment expression.
Python developers might be already familiar with the concept of sequence unpacking. CoffeeScript also already has the syntax for destructuring. SpiderMonkey, the JavaScript engine in Firefox, has been supporting destructuring assignment for a while. The latest ECMAScript 6 defines the grammar for destructuring assignment in Section 11.13.1. There are two different forms: array pattern and object pattern.
Array Pattern
Variables can be initialized in one go. The following two lines have the same effect, the first one is employing an array pattern.
var [m, d, y] = [3, 14, 1977];
var m = 3, d = 14, y = 1977;
Swapping two variables is rather trivial, this one works just as expected. Internally, it does the sequence as if there is a temporary variable temp and the usual value exchange.
x = 3; y = 4; [x, y] = [y, x]
temp = [y, x]; x = temp[]; y = temp[1];
Another typical use of array restructuring is for a function which has multiple return values. We don’t need to wrap it in an object anymore. Also, there is no need to accept all elements in the array.
function now() { return [2, 6, 2013, 8, ]; }
var [m, d] = now(); // m = 2, d = 6
var [,,year] = now(); // year = 2013
With the syntax visualization feature of Esprima, it is rather easy to illustrate the syntax tree of an array pattern. The following figure shows an example thereof. Compared to a vanilla assignment or variable declarator, the obvious different here is that we have an array pattern instead of a plain identifier.
Object Pattern
This pattern is very similar, except it works by matching object properties instead of array indices. Thus, we can easily pick the ones we are interested in while ignoring the rest. A similar example as before, e.g. when processing the return value of a function:
function today() { return { d: 6, m: 2, y: 2013 }; }
var { m: month, y: year } = today(); // month = 2, year = 2013
Of course, instead of a pattern, nothing stops you from assigning a holder object before accessing each property. However, the lack of such extra object makes the code looks cleaner (or sweeter, since destructuring is supposed to be a syntactic sugar), in particular when it is part of a loop.
books.forEach(function ({ title: title, author: author }) { console.log(title, author) }; )
In the above construct, every element in that books array may contain a lengthy information about that particular book. Since we just want some properties, it is possible to extract them directly via the object pattern.
It gets even more interesting once we combine with array comprehension. For example, the following line is exactly the same as the above snippet:
[console.log(t,a) for ({title: t, author: a} of books)];
How do you plan to (ab)use array and object pattern?