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);
}