206

EDIT After looking at JSHint I found this 'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz) and this however after reading it I still don't understand why it is used

I have come across the following code on MDN

var ui = require("sdk/ui");
var { ActionButton } = require("sdk/ui/button/action");

What do the braces on the second line do and why are they used? Why are there no braces on the first line?

Georgi Georgiev
  • 3,174
  • 5
  • 25
  • 34
  • 3
    I think that's an EcmaScript 6 destructuring binding pattern. – Pointy Aug 07 '14 at 16:50
  • @Pointy after looking at JSHint I found this 'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz) and this however after reading it I still don't understand why it is used https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1.7 – Georgi Georgiev Aug 07 '14 at 16:54
  • 5
    @Bergi surely closing this as a duplicate of a pre-ES6 question whose answers claim that this is a JS 1.7 feature unique to Firefox isn't helpful? The world has changed since that question was asked and the answers there are obsolete - plus this question is drawing far more views. We should improve this Q&A pair to clearly include the history of this syntax so that nobody gets confused about the relationship between JS 1.7 and ES 6, then close the *other* question as a duplicate of *this* one. – Mark Amery Nov 23 '15 at 11:21
  • @MarkAmery: Both these questions *ask* about the JS 1.7 feature, and are even tagged [tag:firefox]. For ES6 questions, I'm using [Javascript object bracket notation on left side to assign](http://stackoverflow.com/q/26999820/1048572) as the canonical question. – Bergi Nov 23 '15 at 16:19
  • @Bergi Hmm. Given the context in which he found this code, you're clearly right that the code the OP was reading was using the JS 1.7 feature, but I think the OP in this case has come across this syntax and *doesn't know* which version of the syntax he's seeing. Wouldn't it be more useful to have a comprehensive duplicate target that explains that there are two specifications that introduce the syntax (as well as any differences between the two, although I think they're identical and the ES spec just copied the JavaScript 1.7 version exactly)? – Mark Amery Nov 23 '15 at 16:26
  • @MarkAmery: Sure, go ahead, you'll have my support for creating a new canonical post. – Bergi Nov 23 '15 at 16:35
  • This question is marked as a duplicate but it is better formulated and much more googlable and even has a better answer. – Vojtěch Dohnal Jul 31 '18 at 12:52

1 Answers1

262

This is what's known as a destructuring assignment, and it's a new feature of JavaScript 1.7 (and ECMAScript 6) (Currently, only available as part of the Firefox JavaScript engine.) Roughly, it would translate into this:

var ActionButton = require("sdk/ui/button/action").ActionButton;

It seems silly in this example, as there's only one item being assigned. However, you'd be able to use this pattern to assign multiple variables at once:

{x, y} = foo;

Is the equivalent to:

x = foo.x;
y = foo.y;

This can also be used for arrays. For example, you could easily swap two values without using a temporary variable:

var a = 1;
var b = 3;

[a, b] = [b, a];

Browser support can be tracked using kangax' ES6 compatibility table.

Teymour Aldridge
  • 1,271
  • 9
  • 23
Mike Christensen
  • 77,193
  • 46
  • 189
  • 300
  • Should `ActionButton = ...` be `var ActionButton = ...`? This example wouldn't declare a global -- right? – Casey Falk Aug 07 '14 at 16:53
  • 60
    A much more useful example would be something like `{width, height, color} = options`, which would replace the lines `width = options.width; height = options.height; color = options.color`. – meager Aug 07 '14 at 16:55
  • Or an inside out object. – Joe Kasavage Aug 07 '14 at 17:01
  • 3
    @CaseyFalk - From what I can tell, `var {x, y} = ...` would be the equivalent of `var x = ...` and `var y = ...` and `{x, y} = ...` would be the equivalent of `x = ...` and `y = ...` – Mike Christensen Aug 07 '14 at 17:07
  • 2
    @CaseyFalk - In other words, you're right. Since the example above was declaring `{ ActionButton }`, my *rough translation* was incorrect. I've updated it. – Mike Christensen Aug 07 '14 at 17:08
  • 1
    I realize it was "rough" -- sorry to be nit-picky. : ) Have an upvote. – Casey Falk Aug 07 '14 at 17:13
  • 3
    "JavaScript 1.7 support was introduced in Firefox 2 (October 2006)" :D Anyway, it is part of the ECMA-6 draft ([assignment](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-assignment), [binding](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-destructuring-binding-patterns)), so it will [get broader browser support](https://code.google.com/p/v8/issues/detail?id=811#c15) in the foreseeable future. Also: `(function(arg1, {opt1, opt2}) { console.log(arg1, opt1, opt2); })(1, {opt1: 2, opt2: 3})`. Also: `var {ActionButton: ab} = ...;` – nmaier Aug 07 '14 at 17:36
  • Is the last example still destructuring, since it uses brackets instead of curly braces? – Netside Jul 05 '20 at 02:23
  • The first is an example of destructuring objects, the second is an example of destructuring arrays. https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/ – Mike Christensen Jul 05 '20 at 16:26
  • Your last example switching values of two variables: Looks very neat, but to say 'without using a temporary variable" is a little misleading as you are implicitly creating an array containing the two values taken from the variables, then assigning those values back to the original variables. So, aren't you actually creating a temporary array plus two temporary variables? Wouldn't it be faster simply to use one temporary variable? – JohnRC Oct 09 '20 at 15:23