21. Iterator
大约 2 分钟
Iterator
Iterator(迭代器)是一种接口,或者说是一种机制。它能为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
21.1 作用
为各种数据结构,提供一个统一的、简便的访问接口
使得数据结构的成员能够按某种次序排列
供for...of语句使用
Iterator本质上是一个指针对象
###21.2 指针实现过程
创建一个指针对象,指向当前数据结构的起始位置
第一次调用指针对象的
next
方法,可以将指针指向数据结构的第一个成员第二次调用指针对象的
next
方法,指针就指向数据结构的第二个成员不断调用指针对象的
next
方法,直到它指向数据结构的结束位置
一些数据结构原生就具有Iterator接口,如果没有就必须设置Iterator接口才能使用
普通函数实现Iterator
function myIter(obj){ var i = 0; return { next(){ var done = (i>=obj.length); var value = !done ? obj[i++] : undefined; return { value, done, } } } }
具有Iterator接口的原生数据结构
- Array
- Map
- Set
- String
- 函数的 arguments 对象
- NodeList 对象
//数组的Symbol.iterator方法
var arr = ['a', 'b', 'c'];
var iter = arr[Symbol.iterator]();
//通过next()方法实现每一次的迭代器的遍历
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
/*
value是每次遍历到的值,done代表是否将该数组遍历完全
*/
类数组调用数组的Symbol.iterator方法
var iterable = { 0: 'a', 1: 'b', 2: 'c', length: 3, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; //for...of语句实际上就是对数组使用next()方法直到将数组遍历完全 for (let item of iterable) { console.log(item); // 'a', 'b', 'c' }
注意:
普通对象部署数组的Symbol.iterator方法没有任何效果,必须是要属性值为数值,迭代器内部实际上是通过属性名的自增来实现迭代的
var iterable = { a: 'a', b: 'b', c: 'c', length: 3, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; for (let item of iterable) { console.log(item); // undefined, undefined, undefined }
字符串虽然是一个类数组的对象,也具有Iterator原生接口
var someString = "hi"; typeof someString[Symbol.iterator] // "function" var iterator = someString[Symbol.iterator](); iterator.next() // { value: "h", done: false } iterator.next() // { value: "i", done: false } iterator.next() // { value: undefined, done: true }