遍历器作用:
①为各种数据结构提供一个统一的、简单的访问接口;
②使得数据结构的成员能够按某种次序排列;
③Iterator接口主要供for...of消费。
ES6的有些数据结构原生具备Iterator接口(比如数组,字符串,Set和Map结构),即不用任何处理就可以被for...of循环遍历。原因在于这些数据结构原生部署了Symbol,iterator属性。另外一些数据结构没有,比如对象。
var arr=[1,2,3,4,5,6];
for(let v of arr){
console.log(v);
}
image.png
当可遍历对象被for...of遍历的时候,"[Symbol.iterator]"()就会被调用,返回一个iterator对象,其中还有一个重要的方法:next();
var arr=[1,2,3,4];
let iter=arr[Symbol.iterator]();
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
image.png
原来,for...of的原理就是:先调用可遍历对象的“[Symbol.iterator]”( )方法,得到一个iterator遍历器对象,然后就在遍历器上不断调用next( )方法,直到done的值为true的时候,就表示遍历完成结束了。
let obj={
0:"我是0",
1:"我是1",
2:"我是2",
}
for( let v of obj){
console.log(v);
}
image.png
既然有了Symbol.iterator方法就算是可遍历对象,那么我给Object对象手动加上一个Symbol.iterator方法,那么它是不是可以被for...of遍历了?
自定义iterator遍历器
let obj={
0:"我是0",
1:"我是1",
2:"我是2",
length:3,
[Symbol.iterator](){
let index=0;
return{
next:()=>{
return index<this.length ? {value:this[index++],done:false}:{value:undefined,done:true};
}
};
}
}
for( let v of obj){
console.log(v);
}
image.png
let obj={
0:"我是0",
1:"我是1",
2:"我是2",
length:3,
[Symbol.iterator](){
let index=0;
return{
next:()=>{
return index<this.length ? {value:this[index++],done:false}:{value:undefined,done:true};
}
};
}
}
var iter=obj[Symbol.iterator]();
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
image.png
这就是说,我们可以创建一个可遍历的对象,并且自定义它的遍历行为。或者说可以通过添加Symbol.iterator方法,把一个不可遍历的Object对象,变成可遍历的对象。
iterator使用价值:
新特性for...of之所以能够遍历各种不同的数据结构,正是因为这个数据结构都实现了Iterator遍历器接口,供for...of遍历。如果没有实现Iterator接口,则该数据结构无法被for...of遍历,比如:普通的Object对象。
总结:
Iterator遍历器为各种数据结构提供一个统一的遍历接口,使得for...of能够轻松简便地访问数据成员。 数据结构实现了Iterator接口,我们称之为可遍历对象。我们也可以自己创建可遍历对象并自定义遍历行为。
网友评论