117

I haven't seen this syntax before and am wondering what it's all about.

var { Navigation } = require('react-router');

The brackets on the left are throwing a syntax error:

unexpected token {

I'm not sure what part of the webpack config is transforming or what the purpose of the syntax is. Is it a Harmony thing? Can someone enlighten me?

Micha Wiedenmann
  • 17,330
  • 20
  • 79
  • 123
captainill
  • 1,779
  • 3
  • 15
  • 20
  • In your `webpack.config.js` you probably have [`jsx-loader`](https://github.com/petehunt/jsx-loader) with the `harmony` flag enabled – Paolo Moretti Nov 18 '14 at 17:09

4 Answers4

121

It's called destructuring assignment and it's part of the ES2015 standard.

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.

Source: Destructuring assignment reference on MDN

Object destructuring

 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

Array destructuring

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;
Matt Ball
  • 332,322
  • 92
  • 617
  • 683
  • 4
    Thanks. I'm going to accept this and pose another question. Now that I know what what the syntax is I have to figure out what it's still not compiling in my project. – captainill Nov 18 '14 at 17:34
  • Webpack uses Esprima and will [have support for es6 when Esprima 2.0 is published](https://github.com/webpack/webpack/issues/532). Until then you can use one of the es6-loader which compile it down to es5: https://github.com/conradz/esnext-loader https://github.com/Couto/6to5-loader https://github.com/shama/es6-loader – Johannes Ewald Nov 19 '14 at 16:13
  • 2
    I downvoted this solution because it failed to address the example he gave which is not shown in the solution. The first example shows an object literal being destructured. The second shows an array being destructured. But the example being questioned is this: var { Navigation } = require('react-router'); Furthermore, in the example he gave, the braces are unnecessary. – AndroidDev Feb 07 '17 at 16:06
  • 2
    @AndroidDev you're welcome to suggest an edit; the OP certainly seemed to find the answer satisfactory. – Matt Ball Feb 07 '17 at 16:34
  • 1
    Any idea why the [re]naming is "backwards"? That is, `var {newVarName: oldVarName} = varSource;` looks a lot like `{ newVarName: varSource.oldVarName }` or `scope.newVarName = varSource.oldVarName;`, but those are, obviously, wrong. Is there a practical reason for having the old/existing names on the left of the `:`? – ruffin Feb 23 '17 at 20:36
  • @ruffin you shouldn't think of it like an object declaration where you have name:value pairs (what you would describe as "forward"). Object deconstruction is more like a restricted **with** statement block where you access only a subset of an objects properties. Objects supplied by system (and like) modules tend to have nice, descriptive but rather long (and sometimes conflicting with other objects' property) names so the syntax allows the declaration to optionally include an alias for the property name. So a better way to look at the syntax is ```PropertyName [ ":" Alias ]``` – Uber Kluger Aug 31 '20 at 20:30
114

This is destructuring assignment. It's a new feature of ECMAScript 2015.

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

Is the equivalent to:

var AppRegistry = React.AppRegistry;
var StyleSheet = React.StyleSheet;
var Text = React.Text;
var View = React.View;
user2875289
  • 2,233
  • 1
  • 18
  • 25
Rudolf Manusachi
  • 2,081
  • 2
  • 16
  • 24
19
var { Navigation } = require('react-router');

... uses destructuring to achieve the same thing as ...

var Navigation = require('react-router').Navigation;

... but is far more readable.

Cliff Hall
  • 624
  • 5
  • 12
  • 4
    This directly answers the question as asked and so is probably the best answer to read first, while some of the earlier answers go into more depth. – Mallory-Erik Sep 12 '17 at 17:00
  • 4
    More concise...yes. More readable - not really. The latter example is more explicit using more fundamental constructs, therefor is more readable - but for an expert, the former is more efficient. – Brian Oct 18 '18 at 00:08
6

It's a new feature in ES6 to destructure objects.

As we all know that there is an assignment operation taking place here, Which means right side value is getting assigned to left side variable.

var { Navigation } = require('react-router');

In this case require('react-router') method returns an object with key value pair some thing like

{ Navigation: function a(){}, Example1: function b(){}, Example2: function c(){} }.

And if we would like to take one key in that returned object say Navigation to a variable we can use Object destructing for that.

This will only be possible only if we have the key inhand.

So, after the assignment statement, local variable Navigation will contain function a(){}

Another example looks like this.

var { p, q } = { p: 1, q:2, r:3, s:4 };
console.log(p) //1;
console.log(q) //2;