Iterator迭代器
interator迭代器:只是一种机制,可以为各种不同的数据结构提供统一的循环和迭代规范,而for of循环本身就是基于这种进制进行迭代的!
- 拥有Interator机制的对象,必须具备 next 方法:执行这个方法可以依次访问对象中的每个成员
- 执行next返回值是一个对象:
- value:当前迭代的这一项
- done:记录是否迭代完成
//重写Iterator迭代
class Iterator{
constructor(assemble){
let self = this;
self.assemble = assemble;
self.index = 0;
}
next() {
let self = this,
assemble = self.assemble;
if(self.index > assemble.length - 1){
return {
value:undefined,
done:true
};
}
return{
value:assemble[self.index++],
done:false
};
}
}
let itor = new Iterator([10,20,30]);
console.log(itor.next()); //->{value:10,done:false}
console.log(itor.next()); //->{value:20,done:false}
console.log(itor.next()); //->{value:30,done:false}
console.log(itor.next()); //->{value:undefined,done:true}
Symbol.iterator
虽然不具备 Iterator 内置类,但是对于某些数据结构,它提供了Symbol.iterator 属性方法,这个方法具备迭代器规范,基于这个方法可以依次迭代数据中的每一项
- 数组 Array.prototype[Symbol.iterator]=function...
- Set.prototype / Map.prototype
- String.prototype
- NodeList.prototype
- arguments[Symbol.iterator]
- generator object
- ...
把Symbol.iterator方法执行,会返回一个具备迭代器规范的itor对象,基于itor.next()依次执行,就可以获取到数据集合中的每一项!!
Object.prototype上不具备Symbol.iterator,一个普通的对象默认是不能基于迭代器规范循环的
let arr = [10,20,30];
let itor = arr[Symbol.iterator]();
console.log(itor.next()); //->{value:10,done:false}
console.log(itor.next()); //->{value:20,done:false}
console.log(itor.next()); //->{value:30,done:false}
console.log(itor.next()); //->{value:undefined,done:true}
for...of
ES6中新提供的“for...of”循环,就是按照Iterator迭代器机制去迭代的!!
- 先去找arr[Symbol.iterator]执行(如果数据集合不具备这个属性,就会报错 ‘Uncaught TypeError: {} is not iterable’),返回一个迭代器对象itor 2.每一轮循环都会执行一次 itor.next()方法,把结果中的value赋值给循环中的value;当done为true时,则结束整个循环!!
let arr = [10,20,30];
arr[Symbol.iterator] = function(){
let self = this,
index = 0;
return {
next(){
if(index>self.length - 1){
return {
value:undefined,
done:true
};
};
let result = {
value:self[index],
done:false
};
index += 2;
return result
}
}
};
for (let value of arr){
console.log(value); //依次迭代+2 10,30
}
for...of迭代对象每个属性值
Object.prototype上不具备Symbol.iterator,一个普通的对象默认是不能基于迭代器规范循环的,也就是不能使用for/of
Object.prototype[Symbol.iterator] = function(){
let self = this,
keys = Reflect.ownKeys(self),
index = 0;
return{
next(){
if(index >= keys.length){
return {
value:undefined,
done:true
};
}
return{
value:self[keys[index++]],
done:false
}
}
}
}
let obj = { name:'itor',age:13,lx:0};
for(let value of obj){
console.log(value); // itor,13,0
}
for...of迭代类数组每个值
let obj = {0:10,1:20,2:30,length:3};
obj[Symbol.iterator] = Array.prototype[Symbol.iterator];
for (let value of obj){
console.log(value); // 10,20,30
}