带你认识iterator

迭代器协议是什么

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

只要满足迭代器协议议的对象都可以成为迭代器,迭代器协议,是指对象要定义名为next的无参方法,并且next会返回一个对象,对象包含done(boolean)和value属性,比如:

var iterator = {
    count : 0,
    next : function(){
        return {
            done : this.count > 10,
            value : this.count++
        }
    }
}

这就是一个迭代器

什么是可迭代协议

可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 for..of 结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如 Array 或者 Map,而其他内置类型则不是(比如 Object))。要成为可迭代对象, 一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性

我理解的只要满足可迭代协议的对象,那么就认为这个对象是可迭代的,那么如何迭代呢?就需要对象自身或者原型链上定义迭代方法也就是Symbol.iterator.
Symbol.iterator返回的值就是一个满足迭代器协议的对象,比如:

var iteratorObject = {
    [Symbol.iterator] : function(){
        return iterator;
    }
}

Symbol.iterator迭代器函数

这个函数很多js的内置对象中都有,比如Array、Set、Map、String等但是Object除外,而当我们使用这些对象的时候其实常用到这个函数。

for...of

在使用for...of去迭代一个对象的时候,就会调用此对象的迭代器函数,而如果这个对象是不是可迭代的,不满足迭代器协议,那么会抛出TypeError:object is not iterable
语法

for (variable of iterable) {
    //statements
}

引用MDN的描述

variable : 在每次迭代中,将不同属性的值分配给变量。
iterable : 被迭代枚举其属性的对象。

从这里看,for...of一个可迭代对象的时候,会先执行对象的迭代器函数[Symbol.iterator]获取迭代器,获取带迭代器之后在执行迭代器的next()函数,将返回值赋值给for...of的变量

var iterator = {
    count : 0,
    next : function(){
        console.log("执行了next");
        return {
            done : this.count > 10,
            value : this.count++
        }
    }
}

var iteratorObject = {
    [Symbol.iterator] : function(){
        return iterator;
    }
}

for(let i of iteratorObject){
    console.log("在迭代了");
}

可以看到

输出

每次迭代都是先执行一次next,然后把返回值赋值给变量,然后在执行for...of内部的部分

除了for...of还有yield*,结构赋值,展开语法(...)都会用到对象的迭代器方法

posted @ 2020-09-01 11:13  j植树  阅读(133)  评论(0编辑  收藏  举报