JavaScript Iterables and Iterators
JavaScript 提供了一个迭代数据结构的协议。该协议定义了如何使用 for...of
循环迭代这些数据结构。
该协议的概念可以分为
- iterable (可迭代对象)
- iterator (迭代器)
iterable 协议指出,一个可迭代对象应具有 Symbol.iterator
键。
JavaScript Iterables (可迭代对象)
拥有 Symbol.iterator()
方法的数据结构称为可迭代对象。例如,Arrays(数组)、Strings(字符串)、Sets(集合)等。
JavaScript Iterators (迭代器)
迭代器是 Symbol.iterator()
方法返回的对象。
迭代器协议通过 next()
方法一次访问可迭代对象(数据结构)的每个元素。
让我们来看一个可迭代对象拥有 Symbol.Iterator()
的示例
const arr = [1, 2 ,3];
// calling the Symbol.iterator() method
const arrIterator = arr[Symbol.iterator]();
// gives Array Iterator
console.log(arrIterator);
const str = 'hello';
// calling the Symbol.iterator() method
const strIterator = str[Symbol.iterator]();
// gives String Iterator
console.log(strIterator);
输出
Array Iterator {} StringIterator {}
在这里,调用数组和字符串的 Symbol.iterator()
方法会返回它们各自的迭代器。
Iterate Through Iterables (迭代可迭代对象)
您可以使用 for...of
循环迭代这些可迭代对象。您可以这样迭代 Symbol.iterator()
方法
const number = [ 1, 2, 3];
for (let n of number[Symbol.iterator]()) {
console.log(n);
}
输出
1 2 3
或者您可以像这样直接迭代数组
const number = [ 1, 2, 3];
for (let n of number) {
console.log(n);
}
在这里,迭代器允许 for...of
循环迭代数组并返回每个值。
JavaScript next() Method (next() 方法)
迭代器对象有一个 next()
方法,该方法返回序列中的下一个项。
next()
方法包含两个属性:value
和 done
。
- value (值)
value
属性可以是任何数据类型,表示序列中的当前值。 - done (完成)
done
属性是一个布尔值,指示迭代是否完成。如果迭代未完成,则done
属性设置为false
,否则设置为true
。
让我们来看一个数组可迭代对象的示例
const arr = ['h', 'e', 'l', 'l', 'o'];
let arrIterator = arr[Symbol.iterator]();
console.log(arrIterator.next()); // {value: "h", done: false}
console.log(arrIterator.next()); // {value: "e", done: false}
console.log(arrIterator.next()); // {value: "l", done: false}
console.log(arrIterator.next()); // {value: "l", done: false}
console.log(arrIterator.next()); // {value: "o", done: false}
console.log(arrIterator.next()); // {value: undefined, done: true}
您可以重复调用 next()
来迭代 arrIterator
对象。
next()
方法返回一个具有value
和done
两个属性的对象。- 当
next()
方法到达序列末尾时,done
属性将设置为false
。
让我们看看 for...of
循环如何执行上述程序。例如,
const arr = ['h', 'e', 'l', 'l', 'o'];
for (let i of arr) {
console.log(i);
}
输出
h e l l o
for...of
循环执行的操作与上面的程序完全相同。
for...of
循环不断地在迭代器上调用 next()
方法。一旦达到 done:true
,for...of
循环就会终止。
User Defined Iterator (用户定义的迭代器)
您还可以创建自己的迭代器并调用 next()
来访问下一个元素。例如,
function displayElements(arr) {
// to update the iteration
let n = 0;
return {
// implementing the next() function
next() {
if(n < arr.length) {
return {
value: arr[n++],
done: false
}
}
return {
value: undefined,
done: true
}
}
}
}
const arr = ['h', 'e', 'l', 'l', 'o'];
const arrIterator = displayElements(arr);
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
输出
{value: "h", done: false} {value: "e", done: false} {value: "l", done: false} {value: "l", done: false} {value: "o", done: false} {value: undefined, done: true}
在上面的程序中,我们创建了自己的迭代器。displayElements()
函数返回 value
和 done
属性。
- 每次调用
next()
方法时,该函数都会执行一次并显示数组的值。 - 最后,当数组的所有元素都耗尽时,
done
属性将设置为true
,value
为undefined
。
另请阅读