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就可以完成任务,但是不符合标准时,就报错。

posted @ 2018-07-24 11:05  T&Y  阅读(2595)  评论(0编辑  收藏  举报