web-dev-qa-db-fra.com

Propagation indéfinie dans le tableau vs l'objet

Pourquoi la propagation non définie dans un objet renvoie-t-elle un objet vide? {...undefined} // equals {}:

console.log({...undefined})

Et pourquoi la propagation non définie dans un tableau vous donne-t-elle une erreur? [...undefined] // type error:

console.log([...undefined])
31
0xtimur

Comme indiqué dans les commentaires, et résumé par @ftor de # 687 , la répartition des objets est équivalente1 to Object.assign () (issues # 687 , # 45 ), où en tant que propagation dans le contexte littéral du tableau est une propagation itérable.

Citant Ecma-262 6. , Object.assign () est défini comme:

19.1.2.1 Object.assign (cible, ... sources)

La fonction assign est utilisée pour copier les valeurs de toutes les propriétés propres énumérables d'un ou plusieurs objets source vers un objet cible. Lorsque la fonction assign est appelée, les étapes suivantes sont effectuées:

  1. Soit ToObject (cible).
  2. ReturnIfAbrupt (à).
  3. Si un seul argument a été passé, revenez à.
  4. Soit les sources List des valeurs d'argument commençant par le deuxième argument.
  5. Pour chaque élément nextSource des sources, dans l'ordre d'index croissant, faites
    1. Si nextSource est non défini ou null , laissez les clés être un vide - Liste .
    2. Autre, ...

... suivi de la description de la copie de ses propres propriétés. Le brouillon des propriétés de repos/propagation d'objet est ici . Il ne fait pas partie de l'Ecma-262 6.0.

Un SpreadElement dans une expression littérale de tableau est défini pour commencer comme suit:

SpreadElement: ... AssignmentExpression

  1. Soit spreadRef le résultat de l'évaluation de AssignmentExpression.
  2. Soit spreadObj soit GetValue ( spreadRef).
  3. Soit itérateur soit GetIterator ( spreadObj).
  4. ReturnIfAbrupt (itérateur).

Et puisque undefined n'a pas de propriété avec la clé @@ iterator , une TypeError est lancé, basé sur les étapes de GetIterator . La norme n'est pas facile à lire, mais si je ne me trompe pas, le chemin de l'erreur est GetIterator -> GetMethod -> GetV - > ToObject , qui lève une TypeError pour undefined et null.

Un remède simple à l'utilisation de variables avec une valeur éventuellement indéfinie dans l'initialisation du tableau est d'utiliser une valeur par défaut:

const maybeArray = undefined;
const newArray = [ ...(maybeArray || []) ];

1: Il y a une différence dans comment les setters sont traités .

28
Ilja Everilä