迭代器是什么?
迭代器并没有那么可怕……
符号迭代器
迭代器并没有那么可怕……
根据MDN 网站文档:
for ...of语句创建一个循环,遍历可迭代对象,调用自定义迭代钩子,其中包含要为对象每个不同属性的值执行的语句。
好的……嗯……但是那个 Iterable 对象是什么?
我们几乎每次编写代码都会用到迭代……比如map、filter、for、forEach 等等……
但是for...of语句很特殊,因为:
迭代器(...)将迭代的概念直接引入核心语言,并提供了一种自定义for...of循环行为的机制。
所以你可能会认为for...of循环知道如何遍历数组……但事实并非如此!
我们需要迭代器对象作为“接口”来遍历它:
既然我们知道了这一点……那就开始编写代码吧:
const dogs = ["labrador","chow-chow","cavalier"];
for (let breed of dogs)
{
console.log(breed);
}
//-> labrador, chow-chow, cavalier
在其背后……我们有如下所示的迭代器对象:
const dogs = ["labrador","chow-chow","cavalier"];
let iterator = dogs[Symbol.iterator]();
for (let breed of iterator )
{
console.log(breed);
}
//-> labrador, chow-chow, cavalier (the same result)
等等……什么?
是的……这听起来确实很奇怪,但其实没那么糟糕。
我们再引用一遍:
为了实现可迭代性,对象必须实现`@@iterator`方法,这意味着该对象(或其原型链上的某个对象)必须具有一个键为`Symbol.iterator` 的属性。此函数每次调用都应该返回一个新的迭代器,但这并非强制要求。
这是每个可迭代Symbol.iterator对象都需要具备的属性,以便对其进行循环。
可迭代对象可以是:
字符串
数组
映射集 节点
列表 ...
而所有这些事物,在幕后,都具有这种特性。
符号迭代器
该属性为我们提供了一种next()方法,其工作原理如下:
const dogs = ["labrador","chow-chow","cavalier"];
let iterator = dogs[Symbol.iterator]();
console.log(iterator.next())
//-> {value: "labrador", done: false}
每次调用该next()方法时,我们都会遍历可迭代对象。
现在我们有两个键:
value: "labrador" (可迭代
对象 的当前值)done: false (在它里面有值之前 将为false !)
const dogs = ["labrador","chow-chow","cavalier"];
let iterator = dogs[Symbol.iterator]();
console.log(iterator.next())
//-> {value: "labrador", done: false}
console.log(iterator.next())
//-> {value: "chow-chow", done: false}
console.log(iterator.next())
//-> {value: "cavalier", done: false}
console.log(iterator.next())
//-> {value: undefined, done: true}
done:true是可迭代对象的终点。
JavaScript中还有一些其他强大的工具,它们需要对象是可迭代的。
//TAKE A LOOK AT THE SPREAD OPERATOR...
const number = 31;
let count = [...dogs];
//-> TypeError: dogs is not iterable
const dogs = "labrador";
let doggy = [...dogs];
console.log(doggy)
//-> ["l", "a", "b", "r", "a", "d", "o", "r"]
你必须时刻注意这一点,并且只能使用可迭代对象来操作这类工具!
我想用一种更有趣的方式说再见:
Symbol.iterator这是一个属性……所以……如果你愿意的话,你可以创建自己的可迭代对象!
更多信息: