web-dev-qa-db-ja.com

未定義の配列とオブジェクトの拡散

オブジェクトでundefinedを展開すると、なぜ空のオブジェクトが返されるのですか? _{...undefined} // equals {}_:

console.log({...undefined})

また、配列でundefinedを展開するとエラーが発生するのはなぜですか? _[...undefined] // type error_:

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

コメントに記載されているように、そして #687 の@ftorによって要約されているように、オブジェクトの広がりは同等です1 to Object.assign() (issues #687#45 )、ここで、配列リテラルコンテキストでのスプレッドは反復可能なスプレッドです。

引用 Ecma-262 6.Object.assign() は次のように定義されます:

19.1.2.1 Object.assign(target、... sources)

assign関数は、列挙可能なすべての独自のプロパティの値を1つ以上のソースオブジェクトからターゲットオブジェクトにコピーするために使用されます。 assign関数が呼び出されると、次の手順が実行されます。

  1. ToObject (target)になります。
  2. ReturnIfAbrupt (to)。
  3. 引数が1つだけ渡された場合は、に戻ります。
  4. ソースを、2番目の引数で始まる引数値の List とします。
  5. ソースの各要素nextSourceについて、インデックスの昇順で、を実行します。
    1. NextSourceがndefinedまたはnullの場合、キーを空の List にします。
    2. そうしないと、 ...

...続いて、独自のプロパティのコピーの説明。 Object Rest/Spreadプロパティのドラフトは here です。 Ecma-262 6.0の一部ではありません。

配列リテラル式の SpreadElement は、次のように始まるように定義されています。

SpreadElement...AssignmentExpression

  1. spreadRefAssignmentExpressionの評価結果とする。
  2. spreadObjGetValuespreadRef)とします。
  3. iteratorGetIteratorspreadObj)とします。
  4. ReturnIfAbrupt (イテレータ)。

undefined にはキー @@ iterator のプロパティがないため、手順に基づいてTypeErrorがスローされます GetIterator の。標準は簡単な読み取りではありませんが、私が間違っていない場合、エラーへのパスは GetIterator -> GetMethod -> GetV - > ToObject 、未定義およびnullに対してTypeErrorをスローします。

配列の初期化で値が未定義の可能性がある変数を使用する簡単な方法は、デフォルトを使用することです。

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

1セッターの処理方法 に違いがあります。

28
Ilja Everilä