es6中的Symbol.iterator属性
es6中新引入了一个原始数据类型Symbol,谈到Symbol由不得不说内置的Symbol值,而内置的Symbol值中用的比较多而且和Iterator联系比较紧密的就属Symbol.iterator了。
Iterator是一个遍历器接口,是部署在数据结构上,很多数据结构原生具备Iterator接口,这就意味着我们不需要任何处理就可以使用for..of了,注意:不是可以使用for...of了,而是可以不需要任何处理就可以使用for...of了,看下去就知道为何这样说了。而这很多数据结构就不包括我们自定义的对象,但是我们自定义的对象是不是就不可以使用for...of呢?不是的,但是,但是,但是我们就需要处理一下了(这就是为什么前面要添加一个注意了)。怎么处理呢?我们就要用到我们要谈的Symbol.iterator了。
es6规定,默认的iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是可以遍历的‘可遍历的’,也就是说我们自定义的类,只要部署了Symbol.iterator属性就可以遍历了。对象的Symbol.iterator属性指向其默认遍历器方法,即对象在进行for...of循环时会调用这个方法,返回该对象的默认遍历器....巴拉巴拉,啥意思呢?大概意思就是只要使用for...of 就会调用Symbol.iterator属性,而Symbol.iterator属性返回的就是遍历器对象。那是不是只要部署Symbol.iterator属性他自己就会返回一个遍历器对象呢?对的,但是这个遍历器是需要自己写好的。而不是随便给的对象返回就可以做遍历器了,也就是说我们自己要写好一个对象,这个对象要有一个next()函数,这个next()要返回一个对象,返回的这个对象要有两个属性一个value,一个done(这个可能需要自己去其他的地方了解了)。
首先,我们看一下随便给Symbol.iterator属性返回一个随便对象。
window.onload=function(){ class Obj{ constructor(x,y){ this.x=x; this.y=y; } [Symbol.iterator](){return {};} } var obj=new Obj(1,2); for(var i of obj){ console.log(i) } }
结果:
分析:当使用for...of时,我们会调用[Symbol.iterator](){},而这个函数会返回一个空对象{ },而这个对象并没有next()函数,所以这个时候for...of要用到next(),多以就会出现undefined is not a function
然后,我们给Symbol.itertaor属性返回一个含有next()的对象。
window.onload=function(){
class Obj{
constructor(x,y){
this.x=x;
this.y=y;
}
[Symbol.iterator](){return this;}
next(){
var value=this.x;
if(value<this.y){
this.x++;
return {value:this.x,done:false}
}else{
return {value:undefined,done:true}
}
}
}
var obj=new Obj(1,5);
for(var i of obj){
console.log(i)
}
}
结果:
分析:当使用for..of时,调用Symbol.iterator返回的对象,而现在这个对象也就是Obj本身,为什么要这样呢?这是因为我们需要将iterator接口和数据结构分开,如果像下面这样
window.onload=function(){ var iter={ x:1, y:5, next(){ var value=this.x; if(value<this.y){ this.x++; return {value:this.x,done:false} }else{ return {value:undefined,done:true} } } } class Obj{ constructor(){ } [Symbol.iterator](){return iter;} } var obj=new Obj(); for(var i of obj){ console.log(i) } }
这样iterator接口就和数据结构结合在一起了,这是我们不需要的。
总结:也就是说,Symbol.iterator属性返回的对象不管是什么对象(本身并不是啥iterator接口),都会在使用for...of时被当作iterator接口,但是当这个对象符合iterator接口的标准时,for...of就可以完成任务,但是不符合标准时,就报错。