探索前端JS领域之-迭代器-可迭代对象

946 阅读4分钟

大家好,我是前端小张同学,今天在这跟大家分享一下JS的迭代器,和可迭代对象的区别吧。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

ok 进入正题

迭代器?

mdn上是这样说的

在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。

一旦创建,迭代器对象可以通过重复调用 next()显式地迭代。迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。在产生终止值之后,对 next()的额外调用应该继续返回{done:true}。

Javascript 中最常见的迭代器是 Array 迭代器,它只是按顺序返回关联数组中的每个值。虽然很容易想象所有迭代器都可以表示为数组,但事实并非如此。数组必须完整分配,但迭代器仅在必要时使用,因此可以表示无限大小的序列,例如 0 和无穷大之间的整数范围。

这是一个可以做到这一点的例子。它允许创建一个简单的范围迭代器,它定义了从开始(包括)到结束(独占)间隔步长的整数序列。它的最终返回值是它创建的序列的大小,由变量 iterationCount 跟踪。

总结一下

迭代器 : 就是一个普通的JavaScript对象 , 它必须包含 next 方法 , 且 next方法返回一个对象,该对象必须包含 done和value属性 , done 的值类型为 Boolean 可选的 value 为 any,也是可选的 ,且需要遵循[迭代协议](htt 0://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols)

注意 : next 方法返回一个对象 , 该对象 包含 done 和 value 属性 ,当该 对象迭代完成时 , 没有下一个的时候 done 返回的值为 true value 为 undefined

让我们来实现一个简单的迭代器对象吧

// 首先迭代器 是一个 javascript 对象 

// 创建一个 JavaScript迭代器对象 , 且该对象 必须包含next方法 

// next 方法返回一个对象 , 该对象 包含 done 和 value 属性 ,当该 对象迭代完成时 , 没有下一个的时候 done 返回的值为 true value 为 undefined 

const hobbys = ['篮球' , '足球' , '羽毛球']

const iterator = {
    next () {
         // 默认索引是 0 
         let index = 0
         // next 返回一个 对象
        return {done : false , value : hobbys:[index]}
        // ok 那我们说了 如果该对象没有下一次 迭代 的结果值 了 则 done 为 true value 为 undefined 
        //那我们  是不是需要 做一下边界处理
        
        if(index < names.length) {
          return { done : false , value : names[index ++ ] }
        }
        else {
          return { done : true , value : undefined }
        }
    }
}


console.log(iterator.next())

// 如果你

for (const item of iterator) {
  console.log(item);
}

// 那想必 控制台 会 
TypeError: iterator is not iterable
    at Object.<anonymous> (D:\资料\JS进阶\JS进阶练习\17-认识迭代器_生成器\01_认识迭代器和迭代器的结构.js:27:20)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

ok 到这里我们实现了 一个迭代器对象

for of 遍历可迭代对象

这样就能够通过 for of 遍历对象了 吗?

答案肯定是 哒咩 , 不可以

那接下来我们来说一下 ,怎么实现一个 可迭代的对象

可迭代对象实现原则规范

要点1 : 必须拥有 [Symbol.iterator] 方法 , 并且 该方法 返回一个 迭代器对象 , 这样的对象即可称为 可迭代对象

实现

const iterator = {
  names : ["张三" , '李四' , '王五'],
  [Symbol.iterator] : function () {
    let index = 0
    return {
      next : () => {
        if(index < this.names.kength) {
          return  { done : false , value : this.names[index ++ ] }
        }
        else {
          return { done : true , value : undefined }
        }
      }
    }
  }
}
/*接下来 你通过 for of 即可 遍历该对象 
  for (const item of iterator) {
    console.log(item);
  }

输出 
张三
李四
王五

*/

通常 我们 通过 for of 遍历一个不包含 [Symbol.iterator] 属性的对象时 控制台会告诉你 当前对象是一个不可迭代的对象 , 但是 ,如果 你的对象中 有 Symbol.iterator 函数 并且还返回了 一个迭代器 则 该对象就是一个 可迭代对象

常见的可迭代对象 属性

Array set map weakMap  weakSet , String 等等

    for (item of Array ) {
        console.log(item)
    }
    
    for (item of set ) {
        console.log(item)
    }

知识点验收

问一下自己 , 什么是迭代器 ? 什么是可迭代对象

迭代器 : 一个js普通对象 但 该对象 必须有 next 函数 ,且是无参 或者一个参数 的函数 ,当对象不可继续迭代时 , 返回的done的值 为 true value为 undefined , 反之 done 为 false value为 输出的值

可迭代对象: 一个对象 必须有 [Symbol.iteartor] 方法 , 且该方法 返回一个 迭代器对象 ,这样的对象称为 可迭代对象。

结束

ok ,迭代器 , 和可迭代对象就到这里告一段落了,谢谢大家,如果你觉得有用,请点个👍