déstructuration d'objets sans var


97

Pourquoi la déstructuration d'objet génère-t-elle une erreur s'il n'y a pas de varmot clé devant elle?

{a, b} = {a: 1, b: 2};

jette SyntaxError: expected expression, got '='

Les trois exemples suivants fonctionnent sans problème

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

Question bonus: Pourquoi n'avons-nous pas besoin d'un varpour la déstructuration des tableaux?

J'ai rencontré le problème en faisant quelque chose comme

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Réponses:


158

Le problème vient des {...}opérateurs ayant plusieurs significations en JavaScript.

Quand {apparaît au début d'une instruction , cela représentera toujours un bloc , qui ne peut pas être attribué. S'il apparaît plus tard dans l' instruction en tant qu'expression , alors il représentera un objet.

Les varaide à faire cette distinction, car elle ne peut pas être suivie d'une déclaration , tout comme les parenthèses de regroupement :

( {a, b} = objectReturningFunction() );

De leur documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

Remarques: Les parenthèses (...) autour de l'instruction d'affectation sont obligatoires lors de l'utilisation d'une affectation de déstructuration littérale d'objet sans déclaration.

{a, b} = {a: 1, b: 2} n'est pas une syntaxe autonome valide, car le {a, b} sur le côté gauche est considéré comme un bloc et non comme un objet littéral.

Cependant, ({a, b} = {a: 1, b: 2}) est valide, tout comme var {a, b} = {a: 1, b: 2}

Votre expression (...) doit être précédée d'un point-virgule ou elle peut être utilisée pour exécuter une fonction sur la ligne précédente.


S'il apparaît plus tard dans l'instruction en tant qu'expression, alors il représentera un objet. Cela signifie-t-il que nous ne pouvons jamais avoir de champ de blocage à l'intérieur de parenthèses de regroupement
sharad_kalya

La pointe des parenthèses de regroupement est excellente.
James Smith

C'est une connaissance brillamment obscure qui m'a laissé perplexe. Il permet la déstructuration à travers la portée (enfin, en quelque sorte - vous devez toujours déclarer vos variables, bien sûr). Mais cela résout une contrainte d'utilisation des chaînes Promise tout en ayant besoin d'utiliser plusieurs variables résolues d'une étape d'une chaîne Promise à une autre, sans créer trop de désordre. Merci.
Kevin Teljeur

22

Si vous écrivez du Javascript sans point - virgule , la syntaxe `` affectation sans déclaration '' doit être précédée d'un point-virgule pour qu'elle fonctionne de manière prévisible

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

Je voulais juste le souligner au fur et à mesure que cela me surprenait, et j'espère que cela permettra aux autres de gagner du temps à comprendre pourquoi cela ne fonctionne pas et / ou produit des résultats étranges avec des formateurs de code comme prettier.

En effet, il est en fait juste là dans la réponse acceptée (dernière ligne de la documentation citée) mais facile à manquer, surtout sans voir d'exemple!


1
Ouais. Une raison pour laquelle les gens utilisent des points-virgules!
jfriend00

0

Voici une autre façon:

let {} = {a, b} = objectReturningFunction()

Avantages:

  • Aucune parenthèse nécessaire
  • Aucun point-virgule nécessaire
  • La mission supplémentaire est un no-op garanti (étant donné qu'il ne se passe pas de choses étranges)

Les inconvénients:

  • !(){...}() Ça a l' air un peu bizarre, bien qu'à mon avis pas plus bizarre que l' IIFE .
  • Peut-être déroutant pourquoi il est là. Il est garanti de décourager les gens lors de la première rencontre, je vous déconseille donc de l'utiliser comme une seule fois.

Type de se sent comme de Ia vie sont plus comparables à ;({ a, b })que let {} = { ... }. Belle astuce cependant. :)
shuckster

@ proto-n, +1, idée très intelligente. Comment avez-vous découvert cela?
Pacerier
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.