迭代器对象 Iterator

一、迭代器是什么

在JavaScript中,迭代器也是一个具体的对象,这个对象需要符合迭代器协议(iterator protocol)

1. 迭代的定义:从一个数据集合中按照一定的顺序,不断取出数据的过程称为迭代

2. 迭代和遍历的区别

     迭代:迭代强调的是依次取数据的过程,并不保证取多少,也不保证把所有的数据都取完

     遍历:遍历强调的是要把整个数据依次全部取出

迭代器(iterable)是一个接口! 可以遍历具有该数据结构的对象,为各种容器提供了公共的操作接口,隔离对容器的遍历操作和底层实现,从而解耦

可迭代对象(Iterable)是指实现了可迭代协议(Iterable Protocol)的对象。换句话说,可迭代对象是具有 Symbol.iterator 方法的对象,该方法返回一个迭代器对象。,对象中有一个next方法,next方法的返回值是一个对象,该对象中包含一个布尔值done:代表当前是否迭代完成和一个当前正在迭代的元素值value

    let index = 0
    const days= ["星期一", "星期二", "星期三", "星期四",]
    const daysIterator = {
      next: function () {
        if (index < days.length) {
          return { done: false, value: days[index++] }
        } else {
          return { done: true, value: undefined }
        }
      }
    }
    console.log(daysIterator.next()) // {done: false, value: '星期一'}
    console.log(daysIterator.next()) // {done: false, value: '星期二'}
    console.log(daysIterator.next()) // {done: false, value: '星期三'}
    console.log(daysIterator.next()) // {done: false, value: '星期四'}
    console.log(daysIterator.next()) // {done: true, value: undefined}
    console.log(daysIterator.next()) // {done: true, value: undefined}

二、可迭代对象

  • 通过可迭代对象中的迭代器工厂函数 Symbol.iterator 来生成迭代器。
  • 如果我们希望一个对象可以迭代,必须为对象添加一个名为Symbol.iterator的方法(一个专门使对象可迭代的内建Symbol)
  • 当一个对象实现了iterable接口时,它就是一个可迭代对象
  • 这个对象的要求是必须实现iterator 方法,在代码中我们使用 Symbol.iterator 访问该属性

注意:

        1):如果可迭代对象在迭代期间被修改了,迭代器得到的结果也会是修改后的。

        2):当我们迭代到 done: true之后,再调用next是不是会报错的,到的结果一直都会是 { value: undefined, done: true }

        3):对象并是没有实现这个迭代协议,所以不能使用for of进行遍历

        4):常见的可迭代对象包括数组、Set、Map、String,Array,Set,arguments,NodeList 等,它们都实现了可迭代协议,因此可以直接在 for…of 循环中使用

        5):Array 实例实现了iterable接口迭代协议

三、给对象添加iterator接口

目的:使用for of遍历对象

只需给要被遍历的对象自身或者原型上添加[Symbol.iterator]属性,当使用for of进行遍历时会自动执行该函数(下面代码是将该属性挂载在对象自身)

const infos = {
      name: "xiaozhi",
      age: 22,
      height: 1.77,
      [Symbol.iterator]: function() {
        const entries = Object.values(this)
        let index = 0
        const iterator = {
          next: function() {
            if (index < entries.length) {
              return { done: false, value: values[index++] }
            } else {
              return { done: true }
            }
          }
        }
        return iterator
      }
    }

//【遍历对象】 可迭对象可以进行for of操作
    for (const item of infos) {
      console.log(value)
    }

前面说了只有当一个数据结构具有iterator接口时,才能被for of遍历,但是对象本身不具备该接口,上面代码我们在infos对象自身添加了一个[Symbol.iterator]属性该属性对应一个函数,于是在使用for of进行遍历时,会自动调用该函数执行函数体,在函数体中通过Object构造函数上的 values() 方法是遍历this对象的每一个值得到一个可迭代的数组,然后返回一个next方法,在next方法内部通过闭包实现了局部变量的私有化,当使用for of遍历时会将数组中的值依次赋值给item( item = next().value )


四:一道字节面试题

字节面试官问出这样一道面试题:let [a, b, c] = { a: 1, b: 2, c: 3 },请把它成功解构。

大家都明白对象的解构左边应该是花括号,数组的结构左边应该是中括号,而这道题相反

所以对象为什么能解构?

我们都知道想遍历对象有2种方式:

1.for in

2.Object.keys()先获取key的数组,然后使用数组遍历方式获取key对应的value

所以要想对对象进行解构,要先让对象具有[Symbol.iterator]属性,因此可以将该属性添加到Object构造函数的原型对象上通过原型链让所有实例对象访问到该属性,

Object.prototype[Symbol.iterator] = function() {
    return Object.values(this)[Symbol.iterator]()
}

var [a,b] = {a:1,b:2} //[1,2] //new Object()
console.log(a, b);

而我们知道Object构造函数上的values是遍历this对象的每一个值,以数组的形式输出,然后数组再调用迭代器属性。最终就构造了这个对象身上的迭代器,因此我们可以让它正常解构。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值