web-dev-qa-db-fra.com

déstructuration d'objet sans var

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

{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 var pour la déstructuration des baies?

Je suis tombé sur 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();
}
88
alawatthe

Le problème provient du {...} opérateurs ayant plusieurs significations en JavaScript.

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

Le var permet de faire cette distinction, car il ne peut pas être suivi d'une instruction , comme le fera parenthèse de regroupement :

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

De leurs documents: 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 requises lors de l'utilisation d'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.

137
Jonathan Lonowski

Si vous écrivez JavaScript sans point-virgule, la syntaxe 'affectation sans déclaration' doit être précédée d'un point-virgule pour que cela fonctionne de manière prévisible

let a, b

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

Je voulais juste mettre cela en évidence car cela m'a attiré, 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, etc.

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

14
davnicwil