为了账号安全,请及时绑定邮箱和手机立即绑定

阮一峰的iterator遍历器

Iterator 遍历器的概念

JavaScript原有的表示 “集合”的数据结构,主要是数组 array和对象object ,ES6 又添加了Map和 Set, 这样就有了四种数据集合了,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象,这样就需要一种统一的接口机制,来处理所有不同的数据结构。

Iterator 遍历器就是这样一种机制,他是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口。就可以完成遍历操作(即依次操作处理该数据结构的所有成员)。

iterator的作用三个:一是为各种数据结构提供一个统一的,简便的访问接口,二是使得数据结构的成员能够按某种次序排列,三是ES6 创造了一种新的遍历命令for ... of循环,Iterator接口主要提供for...of 使用。

Iterator的遍历过程是这样的。
(1) 创建一个指针对象,指向当前数据结构起始位置,也就是说,这个遍历对象本质上就是一个只针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4) 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员信息。具体来说,就是返回一个包含value,和done两个属性的对象。value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

function makeIterator(array){
       let nextIndex = null;
       return {
           next:function(){
                       return nextIndex < array.length ?  {value: array[nextIndex++],done:false} :{value:undefined,done:true}
// nextIndex++ 先使用nextIndex,在进行加1
                  }
       }
}
let  it = makeIterator(["a","b"]);
it.next()    // {value:"a",done:false}
it.next()     // {value:"b",done:false}
it.next()     // {value:undefined, done: true}

定义了一个makeIterator函数,他是一个遍历器生成函数,作用就是返回一个遍历器对象,对数组["a","b"]执行这个函数,就会返回该数组的遍历器对象(即指针对象)it.

指针对象的next方法,用来移动指针,开始时,指针指向数组的开始位置,然后,每次调用next()方法,指针就会指向数组的下一个成员。
next方法返回一个对象,表示当前数据成员的信息。这个对象具有value和done两个属性,value属性返回当前位置的成员,done属性是一个布尔值,表示遍历是否结束,即是否还有必要再一次调用next方法。

默认Iterator接口

Iterator接口的目的,就是为了所有数据结构,提供了一种统一的访问机制。即for...of循环,当使用for..of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。
一种数据结构只要部署了Iterator接口,我们就称这种数据结构是"可遍历的"iterable
ES6中,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的iterable”,Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数,执行这个函数,就会返回一个遍历器,至于属性名Symbol.iterator ,他是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的,类型为Symbol的特殊值,所以要放在方括号内

const obj = {
       [Symbol.iterator]: function () {
               return {
                          next: function () {
                              return {
                                     value:1,
                                     done: true
                                      }
                               }
                     }
          }
}

对象obj是可遍历的(iterable),因为具有Symbol.iterator属性。执行这个属性,会返回一个遍历器对象。该对象的根本特征就是具有next方法。每次调用next方法,都会返回一个代表当前成员的信息对象,具有value和done两个属性。
ES6 的有些数据结构原生具备 Iterator 接口(比如数组),即不用任何处理,就可以被for...of循环遍历。原因在于,这些数据结构原生部署了Symbol.iterator属性(详见下文),另外一些数据结构没有(比如对象)。凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。

原生具备 Iterator 接口的数据结构如下。

    Array
    Map
    Set
    String
    TypedArray
    函数的 arguments 对象
    NodeList 对象

对于原生部署 Iterator 接口的数据结构,不用自己写遍历器生成函数,for...of循环会自动遍历它们。除此之外,其他数据结构(主要是对象)的 Iterator 接口,都需要自己在Symbol.iterator属性上面部署,这样才会被for...of循环遍历。

对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消