简单理解遍历器Iterator

简介: 简单理解遍历器Iterator

简单理解遍历器Iterator


JS 中表示“集合”的数据结构有:Array、Object、Map、Set等。

需求:需要统一的接口机制,遍历不同表示“集合”的数据结构。

解决方案:遍历器(Iterator)就是这个接口,针对不同的数据结构完成都可遍历。

一般项目里其实不太用使用Iterator,但是理解这个,可能是理解其他的基础,比如生成器。

Iterator 的遍历过程

遍历器对象本质上,就是一个指针对象(联想遍历各种结构的指针)。

(1)创建一个指针对象,指向当前数据结构的起始位置。,

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

怎么添加 Iterator接口

其实就是在数据结构中增加一个Symbol.iterator属性,其是一个返回**Iterator(遍历器)**的函数。

遍历器的本质是个对象,有个next方法(next的本质是函数,所以能调用),其是一个返回{value:xx,done:true/false}的函数。

value属性返回当前位置的成员,done属性是一个布尔值,表示是否遍历结束,即是否还有必要再一次调用next方法。

for of遍历数据结构,就可以得到每次的value

var obj = {
  [Symbol.iterator]: function () {
    const keys = Object.keys(this)
    let p = 0
    return { next: () => {
      const res = { value: this[keys[p]], done: keys.length < p + 1 }
      p++
      return res
    } }
  },
  a: 1,
  b: 2
}
let it = obj[Symbol.iterator]()
// 所谓的迭代器就是一个对象
console.log(it) // { next: [Function: next] }
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }
for (let v of obj) {
  // 和上面一样,输出两次,1、2
  console.log(v)
}

也可使用生成器添加 Iterator接口

生成器执行的时候,直接返回遍历器实例。

var obj = {
  [Symbol.iterator]: function *  () {
    yield 1
    yield 2
  },
  a: 1,
  b: 2
}
let it = obj[Symbol.iterator]()
console.log(it) // Object [Generator] {}
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }
for (let v of obj) {
  // 和上面一样,输出两次,1、2
  console.log(v)
}

天生有Iterator接口的数据结构

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

注意!!!对象没有内置Iterator接口,所以如果不是手动添加,不能使用for of遍历

用数组举例看下:

var arr = [1, 2]
let it = arr[Symbol.iterator]()
console.log(it) // { next: [Function: next] }
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }
for (let v of arr) {
  // 和上面一样,输出两次,1、2
  console.log(v)
}

遍历器的使用场景

  • 解构
  • 扩展运算符
  • 由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口
  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))
  • Promise.all()
  • Promise.race()

和其他遍历语法的比较

主要以遍历数组为例:

  • for:比较繁琐
  • forEach:无法中途跳出forEach循环
  • for in:遍历数组的键名(索引),还有原型链上的键。当然一般遍历对象用的

for of的优点:

  • 有着同for...in一样的简洁语法,但输出的是是当前键对应的值。
  • 可以break、continue和return配合使用。
  • 提供了遍历所有数据结构的统一操作接口。

注意对象不能直接使用for of,因为内置没有Iterator

引用

-阮一峰的es6手册

本文基本是总结这页,所以不明白的,可以多刷这页。

目录
相关文章
|
存储 小程序 前端开发
深入理解微信授权登录流程、用户信息获取和Emoji的存储
深入理解微信授权登录流程、用户信息获取和Emoji的存储
591 0
|
存储 数据采集 缓存
海量数据去重的Hash、bitmap、BloomFilter、分布式一致性hash
海量数据去重的Hash、bitmap、BloomFilter、分布式一致性hash
396 1
node-sass 安装失败 rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libs
检查一下有没有配置python2.7环境变量 npm install -g node-gyp npm install --global --production windows-build-tools(通过管理员打开) npm i -g node-sass
639 1
|
存储 人工智能 数据管理
【云故事探索】基于阿里云助力地理产业2.0落地,实现遥感数据智能化管理
中国某遥感数据服务中心借助阿里云ECS、GPU和OSS服务,成功实现了地理信息产业升级。此前,中心面临数据管理混乱、服务响应慢等问题。通过阿里云的解决方案,构建了全生命周期管理的遥感数据平台,强化了自动化、智能化的数据生产能力,提升了数据服务的准确性和及时性。此外,平台还增强了数据共享,扩大了应用范围。未来,中心计划结合AI技术,探索地理信息3.0时代,利用阿里云的人工智能平台进一步提升数据管理和应用能力。
730 1
|
9月前
|
数据采集 机器学习/深度学习 人工智能
《AI 剧本生成与动画创作解决方案评测报告》
《AI 剧本生成与动画创作解决方案评测报告》
298 8
《AI 剧本生成与动画创作解决方案评测报告》
|
12月前
|
开发框架 Java UED
如何使用 Spring Boot 实现异常处理
如何使用 Spring Boot 实现异常处理
493 2
|
10月前
|
数据采集 XML API
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
|
11月前
|
传感器 人工智能 算法
《C 语言赋能:物联网环境下人工智能应用的能耗优化之道》
在物联网与人工智能融合的时代,C 语言凭借其对硬件的精准控制和算法优化能力,成为解决能耗问题的关键工具。本文探讨了 C 语言在物联网设备中的应用,包括硬件资源管理、算法优化、数据预处理、模型精简和通信优化等方面,旨在实现更节能高效的物联网人工智能系统,推动其在智能家居、工业自动化、智能交通等领域的广泛应用。
199 7
VitePress 构建的博客如何部署到 github 平台?
VitePress 构建的博客如何部署到 github 平台?
253 0
|
Web App开发 JavaScript 前端开发
ChatGPT与基于GUI的自动化测试
ChatGPT与基于GUI的自动化测试,chrome浏览器+ cypress +HTML代码需要主机名脚本语言和测试目标的URL。
178 10