Iterator迭代器

75 阅读1分钟

Iterator迭代器

虽然浏览器没有内置的Iterator类,但是它给了很多数据结构,都提供了迭代的接口方法 Symbol.iterator

@1 比如:数组结构、类数组【arguments/NodeList/HTMLCollection】、字符串、Set/Map、generator object

@2 Object.prototype 不具备Symbol.iterator

@3 具备这个接口是的数据结构、就可以基于for of 进行循环

/*
	内部处理
	@1 let itor = arr[Symbol.iterator];
	@2 调用 itor.next() 输出 value
	@3 如果 itor.next()中的done为true循环结束
*/
let arr = [10,20,30];
for (const value of arr) {
    console.log(value)
}

手写一个迭代器Iterator

let arr = [10, 20, 30,40];
Array.prototype[Symbol.iterator] = function values() {
    //把值存下来
    let data = this,
        index = 0;
    return {
        next: function () {
            if (index > data.length-1){
                return {
                    value: undefined,
                    done: true
                }
            }
            return {
                value: data[index++],
                done: false
            }
        }
    }
}

for (const value of arr) {
    console.log(value)
}

用for of 遍历一个对象

/*
	思考如何才能使用for of
	思路:
		@1 遍历对象上必须有[Symbol.iterator]方法
		@2 方法必须返回一个对象--对象中包含next函数
		@3 next函数中返回一个对象--对象中包含done和value
		@4 当done为true的时候
*/
Object.prototype[Symbol.iterator] = function values(){
    let data = this,
        index = 0,
        keys = Object.keys(data).concat(Object.getOwnPropertySymbols(data));
    return {
        next:function next(){
            if(index>keys.length-1){
                return {
                    done:true,
                    value:undefined
                }
            }
            return {
                done:false,
                value:data[keys[index++]]
            }
        }
    }
}

for (const value of obj) {
    console.log(value);
}

一个类数组如何使用for of

/*
	对类数组我们一般不手写iterator 直接让他继承Array.prototype[Symbol.iterator]
*/
let obj = {
    0:0,
    1:1,
    2:2,
    3:3,
    4:4,
    length:5
}

//直接继承
obj[Symbol.iterator] = Array.prototype[Symbol.iterator]

for (const value of obj) {
    console.log(value);
}