JavaScript - 用户定义迭代器
在 JavaScript 中,可迭代对象是指在对象原型中具有 Symbol.iterator() 方法的对象。可迭代对象的示例包括数组、集合、映射、字符串等。Symbol.iterator() 方法返回一个包含 next() 方法的对象,该对象称为 iterator。此处,next() 方法每次调用都会返回可迭代对象的元素。
next() 方法
迭代器对象的 next() 方法返回一个包含以下两个键值对的对象。
value − value 键包含元素的值。
done − done 键包含布尔值。如果可迭代对象的所有迭代都已完成,则 done 为 true。否则,结果为 false。
示例
在下面的示例中,我们创建了数组,并将数组迭代器存储在"iter"变量中。之后,我们使用迭代器对象的 next() 方法获取下一个值。
输出显示 next() 方法返回包含"value"和"done"属性的对象。最后一次迭代仅返回包含"done"属性的对象。
<html>
<head>
<title> JavaScript - Iterators </title>
</head>
<body>
<p id = "output"> </p>
<script>
const output = document.getElementById("output");
const nums = [10, 72, 45];
const iter = nums[Symbol.iterator]();
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
</script>
</body>
</html>
输出
{"value":10,"done":false}
{"value":72,"done":false}
{"value":45,"done":false}
{"done":true}
用户自定义迭代器
在上文中,我们了解了 JavaScript 中迭代器的工作原理。Symbol.iterator() 方法返回包含 next() 方法的对象,并且每当执行 next() 方法时,它都会返回一个对象。
因此,我们可以用同样的方式实现用户自定义迭代器。
示例
在下面的示例中,我们使用函数创建了自定义迭代器。该函数返回包含 next() 方法的对象。next() 方法返回包含数组元素的对象,如果 n 小于数组长度,则返回第 n 个索引处的 false 布尔值。如果 n 大于或等于数组长度,则返回仅包含 'done' 属性和 'true' 布尔值的对象。
之后,我们使用 iter.next() 语法获取下一个数组元素。
<html>
<head>
<title> JavaScript - User defined iterators </title>
</head>
<body>
<p id = "output"> </p>
<script>
const output = document.getElementById("output");
function customIterator(chars) {
// 追踪索引
let n = 0;
return {
// next() 方法
next() {
if (n < chars.length) {
return {
value: chars[n++],
done: false
}
}
return {
done: true
}
}
}
}
const chars = ['A', 'C', 'E'];
const iter = customIterator(chars);
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
output.innerHTML += JSON.stringify(iter.next()) + "<br>";
</script>
</body>
</html>
输出
{"value":"A","done":false}
{"value":"C","done":false}
{"value":"E","done":false}
{"done":true}
{"done":true}
以上代码使用函数定义迭代器。因此,您无法将 forof 循环与迭代器一起使用。让我们在下面的示例中学习如何使用对象定义迭代器。
示例
在下面的示例中,我们添加一个函数作为"Symbol.iterator"键的值。该函数返回 next() 方法。next() 方法返回奇数。如果奇数的值为 9,则返回 {done: true} 对象以结束迭代。
这里,我们使用对象创建了迭代器。因此,您可以使用 forof 循环。循环将自动执行迭代器的 next() 方法,并返回 next() 方法返回的对象的"value"属性的值。
<html>
<head>
<title> JavaScript - User defined iterators </title>
</head>
<body>
<p id = "output"> </p>
<script>
const output = document.getElementById("output");
// 空对象
oddNum = {};
// 添加迭代器
oddNum[Symbol.iterator] = function () {
let p = -1;
done = false;
return {
next() {
p += 2;
if (p == 9) return { done: true }
return { value: p, done: done };
}
};
}
for (const odd of oddNum) {
output.innerHTML += odd + "<br>";
}
</script>
</body>
</html>
输出
1 3 5 7
当需要自定义可迭代对象的遍历方式时,应该创建用户自定义迭代器。例如,遍历可选数组元素、从迭代器中获取偶数或奇数等。

