概述:Iterator是ES6新加入的概念,Iterator是一种接口。接口是一系列特征的集合,是方法的声明,是一种抽象概念,同时接口也是实现继承的一种方式。为什么说接口是抽象概念呢,对于OOP语言来说,接口只提供方法的声明,不提供方法的实现,具体实现由其实现类来重写。类可以看成是某一类型具有相同特征的数据结构的描述。通俗来说,就是为实现了接口的不同数据接口提供了统一的特性访问机制。
对于js来说,Iterator有三个作用,一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
一、Iterator遍历的过程:
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next
方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next
方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next
方法,直到它指向数据结构的结束位置。
//实现了Iterator接口的对象都有一个Symbol.iterator属性,是一个方法,返回一个迭代器对象
var arr = [1,2,3,4]
let it = arr[Symbol.iterator]()
it.next() //{value:1,done:false}
it.next() //{value:2,done:false}
it.next() //{value:3,done:false}
it.next() //{value:4,done:false}
it.next() //{value:undefined,done:true}
二、实现原理,开篇已经说过,Iterator是一个接口,不提供具体实现,所以每个实现Iterator接口的对象都自己实现了其next方法
以数组为例,我们自己实现一个迭代器
Array.prototype.myIterator = function() {
let index = 0
let that = this
return {
next: function() {
let done = false
if (index === that.length - 1) {
done = true
}
return {
value: that[index++],
done
}
}
}
}
var arr = [1,2,3]
let it = arr.myIterator()
it.next() //{value:1,done:false}
it.next() //{value:2,done:false}
it.next() //{value:3,done:false}
it.next() //{value:undefined,done:true}
三、js原生具备Iterator接口的对象
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
四、调用Iterator接口的场合
- for...of
- 解构赋值
- 扩展运算符
- yeild * 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
- Array.from() 参数传入一个实现Iterator的接口对象
- Promise.all()
- Promise.race()
- new Set() ,new Map(),new WeakSet(),new WeakMap()