1

タイトルが示すように、ループ変数が にバインドされていない for インデックスを使用for-ofしてループ本体を実行するのに、他の反復構造 ( 、など) は実行しないのはなぜですか?undefinedArrayforEach()for-in

明確化:多くの人が質問を誤解しているため

次のことではありません

  • TypedArraysを繰り返す(スパースにすることはできません) またはのクラス
  • 「正しく」反復する方法まばらArrayに(他のすべての方法は期待どおりに機能するようです)
  • スキップundefined要素Array

MDN にある次の非公式な説明は間違っていますか?

for...ofステートメント [...] は、オブジェクトの個別の各プロパティの値に対して実行されるステートメントを使用して、カスタム反復フックを呼び出します。

つまり、存在しないプロパティに対しても呼び出されます。

const sparse = [0, 1, 2] // Was [0, , 2], but some are unfamiliar with this syntax 
                         // or think it creates the array [0, undefined, 2]
delete sparse[1]
for (let e of sparse) console.log('for-of', e)
// Contrast with:
sparse.forEach(e => console.log('forEach', e))
for (let i in sparse) console.log('for-in', sparse[i])
console.log('map', sparse.map(e => e)) // Note, prints incorrectly in the snippet
                                       // console, check browser console
// etc.

これは意図した動作ですか (はい) & なぜこのように設計されたのですか?

4

1 に答える 1

2

for..of仕様で説明されている Array iterator メソッドを呼び出します。

(2) iterator を ObjectCreate(%ArrayIteratorPrototype%, «‍[[IteratedObject]], [[ArrayIteratorNextIndex]], [[ArrayIterationKind]]») とする。

(4) イテレータの [[ArrayIteratorNextIndex]] 内部スロットを 0 に設定します。

次に、22.1.5.2.1 %ArrayIteratorPrototype%.next:でイテレータが反復されると:

(6) index を O の [[ArrayIteratorNextIndex]] 内部スロットの値とします。

(10) index ≥ len の場合、

(10) (a) O の [[IteratedObject]] 内部スロットの値を未定義に設定します。

(10) (b) CreateIterResultObject(undefined, true) を返す。

(11) O の [[ArrayIteratorNextIndex]] 内部スロットの値を index+1 に設定します。

(値が である反復子結果オブジェクトを作成しますarray[index])

.next()つまり、イテレータはインデックス 0 から反復し、呼び出されるたびにインデックスを 1 ずつ増やします。配列が実際にそのインデックスにアイテムを持っているかどうかを確認するのではなく(スパース配列にはありません)、インデックスが.length配列の よりも小さいことを確認するだけです。

for..in一方、 では、すべての列挙可能なプロパティが反復処理され、配列自体の列挙可能なプロパティには疎な配列インデックスが含まれません。

const sparse = [0, , 2];
console.log(sparse.hasOwnProperty('0'));
console.log(sparse.hasOwnProperty('1'));

はい、これは意図された動作です。

于 2019-04-28T00:01:10.813 に答える