反復はコレクション要素にアクセスするメソッドです。反復可能なオブジェクトは反復可能オブジェクトと呼ばれます。反復子は、走査位置を記憶できるオブジェクトです。反復子オブジェクトは、コレクションの最初の要素からすべての要素が終了するまでアクセスを開始します。にアクセスされた場合、イテレータは前方にのみ移動でき、後方には移動できません。
遅延評価は、「遅延計算」または「遅延計算」と訳されることが多く、実際に実行する必要がある場合にのみ式の値を計算することを指します。
遅延評価の反対は早期評価です。早期評価は貪欲評価または厳密評価とも呼ばれ、ほとんどの従来のプログラミング言語の評価戦略です。
遅延評価の特性を最大限に活用する利点は、主に次の 2 つの側面に反映されます。##Promise.all([反復可能])
const [a, b, ..] = iterable (代入の構造化)
反復可能プロトコル
オブジェクトを反復可能にするには、反復子のファクトリである Symbol.iterator を通じて反復子メソッドを実装する必要があります。 TypeScript を使用すると、反復可能なプロトコルは次のようになります。interface Iterable { [Symbol.iterator]() : Iterator; }
イテレータ プロトコル
イテレータ プロトコルは、一連の値を生成する標準的な方法を定義します。 オブジェクトがイテレータになるためには、next() メソッドを実装する必要があります。イテレータは return() メソッドを実装できます。これについては、この記事で後ほど説明します。 TypeScript を使用すると、イテレータ プロトコルは次のようになります。interface Iterator { next() : IteratorResult; return?(value?: any): IteratorResult; }
interface IteratorResult { value?: any; done: boolean; }
非常に基本的なイテレータである createRangeIterator イテレータから始めます。
手動で it.next() を呼び出して、次の IteratorResult を取得します。最後の呼び出しは {done: true} を返します。これは、イテレーターが使用され、値を生成しなくなったことを意味します。
function createRangeIterator(from, to) { let i = from; return { next() { if (i <= to) { return { value: i++, done: false }; } else { return { done: true }; } } } } const it = createRangeIterator(1, 3); console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next());
この記事の前半で、JS の特定のステートメントには Iterable オブジェクトが必要であると述べました。したがって、前の例は for...of ループとともに使用すると機能しません。
しかし、反復子および反復可能プロトコルに準拠するオブジェクトを作成するのは非常に簡単です。
function createRangeIterator (from, to) { let i = from return { [Symbol.iterator] () { return this }, next() { if (i <= to) { return { value: i++, done: false } } else { return { done: true } } } } } const it = createRangeIterator(1, 3) for (const i of it) { console.log(i) }
迭代器可以表示无限制大小的序列,因为它们仅在需要时才计算值。
注意不要在无限迭代器上使用扩展运算符(...),JS 将尝试消费迭代器,由于迭代器是无限的,因此它将永远不会结束。 所以你的应用程序将崩溃,因为内存已被耗尽
同样,for ... of 循环也是一样的情况,所以要确保能退出循环:
function createEvenNumbersIterator () { let value = 0 return { [Symbol.iterator] () { return this }, next () { value += 2 return { value, done: false} } } } const it = createEvenNumbersIterator() const [a, b, c] = it console.log({a, b, c}) const [x, y, z] = it console.log({ x, y, z }) for (const even of it) { console.log(even) if (even > 20) { break } }
关闭迭代器
前面我们提到过,迭代器可以有选择地使用return()方法。 当迭代器直到最后都没有迭代时使用此方法,并让迭代器进行清理。
for ... of循环可以通过以下方式更早地终止迭代:
break
continue
throw
return
function createCloseableIterator () { let idx = 0 const data = ['a', 'b', 'c', 'd', 'e'] function cleanup() { console.log('Performing cleanup') } return { [Symbol.iterator]() { return this }, next () { if (idx <= data.length - 1) { return { value: data[idx++], done: false } } else { cleanup() return { done: true } } }, return () { cleanup() return { done: true } } } } const it = createCloseableIterator() for (const value of it) { console.log(value) if (value === 'c') { break } } console.log('\n----------\n') const _it = createCloseableIterator(); for (const value of _it) { console.log(value); }
如果知道迭代器已经结束,则手动调用cleanup()函数。
如果突然完成,则return()起作用并为我们进行清理。
【推荐学习:javascript高级教程】
以上がJavaScript の反復可能なオブジェクトとイテレータをご存知ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。