Notation de crochet d'objet Javascript ({Navigation} =) sur le côté gauche de l'affectation

108

Je n'ai jamais vu cette syntaxe auparavant et je me demande de quoi il s'agit.

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

Les crochets sur la gauche lancent une erreur de syntaxe:

jeton inattendu {

Je ne sais pas quelle partie de la configuration du Webpack est en train de transformer ou quel est le but de la syntaxe. Est-ce un truc Harmony? Quelqu'un peut-il m'éclairer?

capitaine
la source
Dans votre webpack.config.jsvous avez probablement jsx-loaderavec le harmonydrapeau activé
Paolo Moretti

Réponses:

112

C'est ce qu'on appelle l' affectation de déstructuration et cela fait partie de la norme ES2015 .

La syntaxe d'affectation de déstructuration est une expression JavaScript qui permet d'extraire des données de tableaux ou d'objets à l'aide d'une syntaxe qui reflète la construction de tableaux et d'objets littéraux.

Source: Référence d'affectation de déstructuration sur MDN

Déstructuration d'objets

 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

Déstructuration du tableau

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
la source
4
Merci. Je vais accepter cela et poser une autre question. Maintenant que je sais quelle est la syntaxe, je dois comprendre ce qu'elle ne compile toujours pas dans mon projet.
captainill
Webpack utilise Esprima et prendra en charge es6 lors de la publication d'Esprima 2.0 . Jusque-là, vous pouvez utiliser l'un des chargeurs es6 qui le compilent en es5: github.com/conradz/esnext-loader github.com/Couto/6to5-loader github.com/shama/es6-loader
Johannes Ewald
2
J'ai décliné cette solution parce qu'elle ne répondait pas à l'exemple qu'il a donné et qui n'est pas indiqué dans la solution. Le premier exemple montre un objet littéral en cours de déstructuration. La seconde montre un tableau en cours de déstructuration. Mais l'exemple en question est le suivant: var {Navigation} = require ('react-router'); De plus, dans l'exemple qu'il a donné, les accolades ne sont pas nécessaires.
AndroidDev
2
@AndroidDev vous êtes invités à suggérer une modification; le PO semble certainement trouver la réponse satisfaisante.
Matt Ball
1
Une idée de la raison pour laquelle le [re] nommage est «à l'envers»? Autrement dit, var {newVarName: oldVarName} = varSource;ressemble beaucoup à { newVarName: varSource.oldVarName }ou scope.newVarName = varSource.oldVarName;, mais ceux-ci sont évidemment faux. Y a-t-il une raison pratique pour avoir les noms anciens / existants à gauche du :?
ruffin
114

C'est une mission de déstructuration . C'est une nouvelle fonctionnalité d'ECMAScript 2015.

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

Est l'équivalent de:

var AppRegistry = React.AppRegistry;
var StyleSheet = React.StyleSheet;
var Text = React.Text;
var View = React.View;
Rudolf Manusachi
la source
17
var { Navigation } = require('react-router');

... utilise la déstructuration pour réaliser la même chose que ...

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

... mais est beaucoup plus lisible.

Cliff Hall
la source
3
Cela répond directement à la question posée et est donc probablement la meilleure réponse à lire en premier, tandis que certaines des réponses précédentes vont plus en profondeur.
Mallory-Erik du
3
Plus concis ... oui. Plus lisible - pas vraiment. Le dernier exemple est plus explicite en utilisant des constructions plus fondamentales, il est donc plus lisible - mais pour un expert, le premier est plus efficace.
Brian
5

C'est une nouvelle fonctionnalité d'ES6 pour déstructurer les objets.

Comme nous le savons tous, une opération d'affectation est en cours ici, ce qui signifie que la valeur du côté droit est affectée à la variable du côté gauche.

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

Dans ce cas, la require('react-router')méthode retourne un objet avec une paire clé-valeur quelque chose comme

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

Et si nous voulons prendre une clé dans cet objet retourné, disons Navigationà une variable, nous pouvons utiliser la destruction d'objets pour cela.

Cela ne sera possible que si nous avons la clé en main.

Ainsi, après l'instruction d'affectation, la variable locale Navigationcontiendrafunction a(){}

Un autre exemple ressemble à ceci.

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