Marius Schulz
Marius Schulz
Front End Engineer

ES2015 Destructuring for Assignments

The ECMAScript 2015 standard introduced the concept of destructuring to JavaScript. Using the destructuring syntax, you can decompose objects and arrays according to a given pattern. Oftentimes, destructuring is used to declare a bunch of new local variables:

const [head, ...tail] = [1, 2, 3, 4, 5];
// head = 1
// tail = [2, 3, 4, 5]

let { x = 0, y = 0, z = 0 } = { x: 100, y: 200 };
// x = 100
// y = 200
// z = 0

var [[x1], [x2], [x3]] = [[10, 20], [30, 40], [50, 60]];
// x1 = 10
// x2 = 30
// x3 = 50

As the above examples show, destructuring works with all three variable declaration keywords: const, let, and var. However, destructuring is not limited to declaring new variables. It can also be used for plain assignment to existing ones:

let x;
let y;

({ x, y } = { x: 100, y: 200 });
// x = 100
// y = 200

Notice the parentheses around the assignment expression. Without them, the JavaScript parser would try to parse a block once it sees the opening brace. Parentheses help disambiguate between the beginning of a block and an object destructuring pattern.

Using destructuring for assignments opens up some interesting possibilities. For instance, swapping the values of two variables no longer requires a temporary variable:

let a = 3;
let b = 5;

// Old approach
var temp = a;
a = b;
b = temp;

// New approach
[a, b] = [b, a];

Note that it's not possible to mix declaration and assignment within one destructuring pattern. If you put const, let, or var in front of the pattern, all variables within the pattern will be declared. Without a keyword in front, there will be no declarations, just assignments.

While destructuring can be an elegant solution to some problems, it doesn't always result in the most obvious code when combined with, say, conditional expressions:

function random(min, max = 0) {
  [min, max] = min > max ? [max, min] : [min, max];

  return Math.random() * (max - min) + min;
}

Although the above destructuring assignment has a strangely satisfying symmetry to it, I'd rather read the following code:

function random(min, max = 0) {
  if (min > max) {
    [min, max] = [max, min];
  }

  return Math.random() * (max - min) + min;
}

As always, readability trumps brevity. Don't try to be too clever; your coworkers and your future you will thank you.