什么是遍历器
Iterator 是一种接口,为各种不同的数据结构提供统一的访问机制(即 for...of 循环)。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- 为各种数据结构(
Array,Object,Map,Set等),提供一个统一的、简便的访问接口 - 使得数据结构的成员能够按某种次序排列
ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费
Iterator 的遍历过程
- 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
- 第一次调用指针对象的
next方法,可以将指针指向数据结构的第一个成员。 - 第二次调用指针对象的
next方法,指针就指向数据结构的第二个成员。 - 不断调用指针对象的
next方法,直到它指向数据结构的结束位置。
简单的迭代器示例
const it = makeIterator(['a', 'b'])
console.log(it.next())
console.log(it.next())
console.log(it.next())
function makeIterator (array) {
var nextIndex = 0
return {
next: function () {
return nextIndex < array.length ?
{ value: array[nextIndex++], done: false } :
{ value: undefined, done: true }
}
}
}
哪些数据结构支持 iterator
ArrayMapSetStringTypedArray- 函数的
arguments对象 NodeList对象
以上数据结构进行 for...of 循环时,该循环会自动去寻找 Iterator 接口。
没有 Iterator 接口的要如何遍历
比如对象(Object)默认是没有 Iterator 接口,那么它就不能被 for...of 遍历
如下所示,for...of 对 Object 遍历,会提示 obj is not iterable,它不是一个遍历器
const obj = { name: 'wfly', age: '18' }
for (item of obj) {
console.log(item);
}
要想不支持 Iterator 接口的,实现 for...of 循环,需要在此数据类型上部署 Iterator 接口,如下
const obj = {
name: 'wfly', age: '18',
[Symbol.iterator]: function () {
var nextIndex = 0
return {
next: function () {
return nextIndex < 3 ?
{ value: nextIndex++, done: false } :
{ value: undefined, done: true }
}
}
}
}
for (item of obj) {
console.log(item);
}
所以只要是部署了
Iterator接口数据结构,那么它就是可被for...of循环遍历的
为什么对象这种数据结构没有部署遍历器接口
- 对象的哪个属性先遍历,哪个属性后遍历是不确定的,因为对象是无序的
- 遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换
- 对象部署遍历器接口并不是很必要,
ES6提供了Map数据结构可供for...of遍历循环
调用遍历器接口的场景
解构赋值
对数组和 Set 结构进行解构赋值时,会默认调用 Symbol.iterator 方法。
let set = new Set().add('a').add('b').add('c');
let [x,y] = set;
// x='a'; y='b'
let [first, ...rest] = set;
// first='a'; rest=['b','c'];
扩展运算符
扩展运算符(…)也会调用默认的 Iterator 接口。
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
所以只要某个数据结构部署了
Iterator接口,就可以对它使用扩展运算符,将其转为数组。
字符串的 Iterator 接口
字符串是一个类似数组的对象,也原生具有 Iterator 接口。
如下所示
var a = '1231231'
for (item of a) {
console.log(item);
}
其他场合
yield*for...ofArray.from()Map(), Set(), WeakMap(), WeakSet()Promise.all()Promise.race()

1432

被折叠的 条评论
为什么被折叠?



