Iterator
Iterator 可翻译为迭代器、遍历器,它为各种数组结构提供了一个统一的访问接口,主要供for of
使用,Iterator 的遍历过程如下
- 创建一个指针对象,指向当前数据结构的起始位置
- 依次调用指针对象的
next
方法,直到数据机构的结束位置
执行指针对象的next
方法时,返回一个包含 value 和 done 两个属性的对象,当 done 为 true 时,代表数据接口遍历结束了。
一个数据结构只要部署了 Iterator 接口,那我们就称它为可遍历的。 Iterator 接口默认部署在Symbol.iterator
属性上。
js
let arr = [1, 2, 3]
let iter = arr[Symbol.iterator]()
let a = iter.next() // { value: 1, done: false }
let b = iter.next() // { value: 2, done: false }
let c = iter.next() // { value: 3, done: false }
let d = iter.next() // { value: undefined, done: true }
for of
当我们使用 for of 尝试遍历一个数据结构时,会去寻找 Iterator 接口,也就是Symbol.iterator
属性。 原生部署了Symbol.iterator
的数据结构有,即下面这些数据结构都能使用for of
来遍历
- Array
- Map
- Set
- String
- arguments
- nodeList
给对象添加迭代器的例子:
js
const obj = {
name: "aa",
alias: "bb",
id: "11",
[Symbol.iterator]: function () {
const values = Object.values(this);
let index = 0;
return {
next() {
const value = values[index++];
if (index === values.length + 1) {
return { done: true };
}
return {
value,
done: false,
};
},
};
}
};
for(let value of obj){
console.log(value) // aa,bb,11
}
for... of 方法会尝试寻找 symbol.iterator
方法,如果方法存在,则会一直调用该方法暴露出来的 next 方法,直至返回 {done: true}
为止。
在这个例子中,我们用 Object.values 取到对象值的数组。存在 values[index]
时,返回 { done: false }
,当 index 已经超出了数组长度,则返回 { done: true }
;