迭代器是一种一次性使用的对象,用于迭代与其关联的可迭代对象
迭代器模式
把某些结构成为可迭代对象,因为它们实现了iterable接口,且可被迭代器iterator消费。
可迭代对象:集合类型的对象,具有有限的元素
默认迭代器 [Symbol.iterator]
调用这个工厂函数会生成一个迭代器
const arr = new Array()
arr[Symbol.iterator]() // ArrayIterator
实现iterable接口的数据类型
如果对象的父类实现了iterable接口,那这个对象也实现了这个接口
- 字符串
- 数组
- Set
- Map
- arguments
- NodeList对象(dom)
- 生成器对象
接收可迭代对象的原生语言特性包括
- for-of循环
- 数组解构
- 扩展操作符
- Array.from()
- 创建Map
- 创建Set
- Promise.all()
- Promise.race()
- yield* 操作符
迭代器
- 迭代器维护一个可迭代对象的引用,所以迭代器会阻止垃圾回收机构回收可迭代对象
- 不同迭代器的实例相互之间没有联系
- 可迭代对象在迭代期间被修改,迭代器也会相应变化。
迭代器工作原理
- 创建一个指针对象,指向数据结构的起始位置
- 第一次调用next(),迭代器将指针指向第一个成员
- 接下来每次调用next()接口,指针都会向后移动,直到最后一个成员
- 每次调用next()方法都会返回一个属性为done、value的对象,{value: 当前成员的值,done: 布尔值}
- value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
- 当遍历结束的时候返回的value值是undefined,done值为true
自定义迭代器
// 函数
function iteratorFun(arr) {
let nextIndex = 0
return {
next: function () {
return nextIndex < arr.length
? { value: arr[nextIndex++], done: false }
: { value: undefined, done: true }
}
}
}
let objIterator = new iteratorFun([1, 2, 3])
console.log(objIterator.next())
console.log(objIterator.next())
console.log(objIterator.next())
console.log(objIterator.next())
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: undefined, done: true }
// class
class Iterator {
constructor(arr) {
this.arr = arr
}
[Symbol.iterator]() {
let count = 0, arr = this.arr;
return {
next() {
return count < arr.length ? { value: arr[count++], done: false } : { value: undefined, done: true }
}
}
}
}
let iterator = new Iterator([1, 2, 3]);
// console.log(iterator[Symbol.iterator]().next())
for (let i of iterator) {
console.log(i)
}
提前终止迭代器
-
for-of循环可通过return、break、continue、throw 提前退出
-
数组迭代器是不能关闭的
let arr = [1,2,3,4,5,6] let iter = arr[Symbol.iterator]() for(let i of iter) { if(i>2) { break } } // 1,2,3 for(let i of iter) { console.log(i) } // 4,5