ES6的迭代器与迭代协议Symbol.iterator

2023-10-29

前言

ES6新增了两个协议:

可迭代协议:对象必须具有Symbol.Iterator属性,属性值为一个函数,当这个对象被迭代时,就会调用该函数,返回一个迭代器。

迭代器协议:描述了迭代器对象的具体规则。

迭代器

迭代器,它是用于访问集合类的标准访问方法,它可以把访问逻辑从不同类型集合中抽象出来,从而避免向外部暴露集合内部的结构。

比如我们访问一个数组可能使用for循环或者map,foreach,filter等for(int i=0; i<array.size(); i++) { ... get(i) ... }, 但是当我们想要遍历链表(linkedlist)的时候就得使用while循环while((e=e.next())!=null) { ... e.data() ... }, 以上两种方式我们都必须知道集合的内部结构是怎么样的我们才可以使用对应的循环方式去循环整个集合,那么这样就造成了很大的耦合度,当我们把一个集合的类型从Arrarlist变成Linkedlist的时候,那么原来客户端的代码必须重写,因为我们集合变了,遍历的方式也必须改成对应的方式。

在js中,当我们要迭代集合(指数组)的时候,我们利用ES6为Array类增加的迭代器属性(iterator),该属性的值为一个函数,该函数返回一个迭代器对象。而Array类的iterator属性可以通过Symbol.iterator来访问。我们执行这个函数来生成该数组的迭代器。

const arr = ['a','b','c','d']
const arrIterator = arr[Symbol.iterator]();

关于什么是Symbol,可以看本文附录。

我们已经得到了数组的迭代器,如果我们需要依次获得数组中的值,我们需要不断地调用迭代器的next方法。

arrIterator.next();
// {value: 'a', done: false}

可以看见执行next方法后返回了数据对象,value键对应的是数组的元素,done代表的时候迭代器是否已经迭代到了数组长度的最后下标。

当迭代器迭代到数组长度以外之后,返回了{value: undefined, done: true}

我们也可以这么写:

for (const n of arrIterator) {
    console.log(n)
}
// a
// b
// c
// d
// e

总结一下:

  • 在Js中迭代器对象实现了可迭代协议,迭代器对象由Symbol.iterator属性的值返回。

  • Symbol.iterator属性的值是一个函数,它返回一个迭代器对象。

  • 迭代器指的是拥有next方法的对象。

  • 该next方法必须返回一个带有value和done的对象。

除了Symbol.iterator,ES6中另外提供三种获取数组迭代器的方法

var arr = ['a','b','c']

entries

const iterator = arr.entries();
iterator.next(); // {value: [0,'a'], done: false}
...
iterator.next(); // {value: undefined, done: true}

可以看到entries提供的迭代器返回的结构与Symbol.iterator相似。只是value键对应的值是,包含当前迭代的数组元素的下标和值的数组。

keys

const iterator = arr.keys()
iterator.next()
// {value: 0, done: false}
...
iterator.next()
// {value: undefined, done: true}

value值是当前迭代的数组元素的下标。

values

const iterator = arr.values()
undefined
iterator.next()
// {value: 'a', done: false}
...
iterator.next()
// {value: undefined, done: true}

value值是当前迭代的数组元素。

附录-Symbol

Symbol是es6新增的类型,它是一个基本类型。

  • symbol属性值对应的值是唯一的,这解决了命名冲突的问题,类似于id的作用。

  • symbol值不能与其他数据进行计算,包括与字符串拼接。

  • for/in ,for/of遍历时不会遍布symbol属性

我们知道symbol可以作为属性值存在。并且它具有唯一的特性,举个栗子:直接let s = Symbol();测试s就是Symbol类型了。怎么说他是唯一的呢?
let s = Symbol(); let ss = Symbol(); s == ss ; 结果是false;或者
let s = Symbol('a'); let ss = Symbol('a'); s == ss ; 结果是false
有人会好奇Symbol('a')里面的参数a又是怎么回事呢?字符串a表示一种修饰,对你当前创建的Symbol类型的一种修饰,作为区分使用,否则当你创建多个Symbol数据时,容易混淆。
现在我们回过头说Iterotor是symbol的内置符号,而字符串a是自定义的符号。

附录-for of

条件语句,可以理解为JavaScript解释器在源代码中会经过不同分支路径。而循环语句则是把这些路径弯曲又折回起点,以重复执行代码中的某部分。

es6定义了一个新循环语句:for/of。

for of 与 for in不相同 (in输出的是下标,of输出的是元素)

for/of循环是专门用于可迭代对象的,什么是可迭代对象呢?

我们前文提到具有symbol.iterator属性的对象就是可以迭代的。而这个对象就是可迭代对象。

对象本身默认是不可迭代的。运行时尝试对常规对象使用for/of会抛出TypeError:

附录-JS中 可迭代的数据类型

Array

Set

Map

WeakMap

WeakSet

可以使用for of或new Set(传入参数的数据类型)检验

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES6的迭代器与迭代协议Symbol.iterator 的相关文章

  • Javascript 函数查找数字的倍数

    创建一个名为的函数multiplesOf 它将接受两个参数 第一个参数是数字数组 第二个参数是数字 该函数应返回一个新数组 该数组由参数数组中的每个数字组成 该数字是参数数字的倍数 So multiplesOf 5 6 7 8 9 10 3
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • 在 contenteditable div 中选择范围

    我有一个contenteditablediv 和其中的一些段落 这是我的代码 div style border solid 1px black width 300px height 300px div Hello world div div
  • Javascript Promise“then”始终运行,即使 Promise 未能执行

    我希望当调用第二个 then 时不执行第三个 then 但是 即使 Promise 被拒绝 调用第二个 then 并且代码返回 rejected 然后返回 undefined 它仍然调用第三个 then 如何不运行第三个 then 这样 未
  • 以编程方式填写reactjs表单

    我正在编写一个用户脚本 但无法填写由reactjs制作的表单 我的代码 document querySelector id username value email protected cdn cgi l email protection
  • IE从哪个版本开始支持Object.create(null)?

    您可以通过多种方式在 JavaScript 中创建对象 creates an object which makes the Object prototype of data var data1 new Object Object liter
  • 如何在react-bootstrap中禁用表单提交的

    在下面的代码片段中 我有许多文本类型的输入表单 如果用户点击 我似乎会得到相同的合成事件 就像他们按下提交按钮一样 我想忽略作为表单提交 只允许一个人按下 提交 按钮 我删除了一些表单组以减少示例 在所有情况下 按钮或 ENTER 键 e
  • 摩卡 - Chai Karma“套件未定义”

    我对 jscript tdd 很陌生 遇到了问题 希望有人能告诉我我在做什么 在浏览器中运行测试 通过 HTML 文件 一切正常 通过节点和业力运行它们我得到以下异常 我想在 node js 主机的 karma 中使用 Mocha 和 Ch
  • 带有淘汰赛js的隐形recaptcha

    我正在完成隐形验证码 但我在实现它时遇到问题 谷歌开发人员页面中的代码显示它应该是这样的
  • 引导程序提前输入未填充承诺的响应

    我的引导程序预输入如下
  • 使用 dc.js 按条形值对条形图中的条形进行排序(排序)

    如何通过维度的计算值而不是维度本身的名称对 dc js 示例中的 x 轴 维度 进行排序 例如 请考虑序数条形图的 dc js 示例 https github com dc js dc js blob master web examples
  • React-Redux:state.setIn() 和 state.set() 有什么区别?

    我见过使用setIn and set 在一些react redux代码中 state setIn state set 我在这里找到了一些文档https facebook github io immutable js https facebo
  • 设置 cookie 时中断 JavaScript 执行

    当设置 cookie 时 是否可以始终中断浏览器开发人员工具中的 javascript 执行 无需显式设置 JS 断点 document cookie 在 html head 块的开头添加此代码片段效果很好
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • window.location 和 location.href 之间的区别

    我对之间的区别感到困惑window location and location href 两者似乎都以相同的方式行事 有什么不同 window location是一个对象 它保存有关当前文档位置的所有信息 主机 href 端口 协议等 lo
  • 正则表达式 - 从 markdown 字符串中提取所有标题

    我在用灰质 https www npmjs com package gray matter 以便将文件系统中的 MD 文件解析为字符串 解析器产生的结果是这样的字符串 n Clean er ReactJS Code Conditional
  • Three.js 各种大小的粒子

    我是 Three js 的新手 正在尝试找出添加 1000 个粒子的最佳方法 每个粒子都有不同的大小和颜色 每个粒子的纹理是通过绘制画布创建的 通过使用粒子系统 所有粒子都具有相同的颜色和大小 为每个粒子创建一个粒子系统是非常低效的 有没有
  • 在 Javascript 中连接空数组

    我正在浏览一些代码 我想知道这有什么用处 grid push concat row 根据我的理解 它等同于 grid push row 为什么要大惊小怪 连接 你想使用 concat当您需要展平数组并且没有由其他数组组成的数组时 例如 va
  • 在 Shopify 商店中嵌入 Vue 组件

    在产品页面中 我尝试显示自定义 Vue 组件 为简洁起见 该组件根据给定的产品 ID 显示 Firebase 数据库中的一些信息 我最初尝试将其制作为 Shopify 应用程序 以便我可以访问他们的 API 我实现了 OAuth 并且可以检
  • Vue.js[vuex] 如何从突变中调度?

    我有一个要应用于 json 对象的过滤器列表 我的突变看起来像这样 const mutations setStars state payload state stars payload this dispatch filter setRev

随机推荐

  • 《C++ System Programming Cookbook》第二章读书笔记

    第二章 C 重要知识点回顾 C primitive types 原生数据类型 char int float double wchar t bool void nullptr t 可用numeraic limits检查范围 sizeof检查大
  • 【翻译】如何在你的IT转型中浪费数以亿计的资金

    你担任范德雷工业公司的首席执行官已经有几年时间了 这是一家在运输领域存在了几十年的巨无霸 真正的战略 你真的希望股价能尽快上涨 这样你就可以在命运之轮转动之前 在最佳的时间点卖掉你的股票 而董事会也不可避免地要把你赶走 你已经厌倦了蒲公英
  • 甘特图排程组件开发(TsyGantt)

    甘特图在Project2000中 很是好用 可是我想在项目开发中还要买了MS的Project2000的版权 所以索性自己开发一套相关的组件
  • 【JavaWeb_Part05】JDBC?弱爆了,看看轻量级的 Mybatis FreeStyle

    开篇 上篇文章我们已经讲了 Mybatis 的入门以及简单的对单表进行增删改查 那么今天我们就来讲一下使用 mybatis 开发dao的两种方式以及 mysql 比较厉害的动态 sql 利用 mybatis 开发 DAO 1 原始的方式开发
  • 多线程之间共享数据的方式探讨

    多线程之间共享数据的方式探讨 方式一 代码一致 如果每个线程执行的代码相同 可以用一个 Runnable 对象 这个 Runnable 对象中存放那个共享数据 卖票系统可以这样做 public class MultiThreadShareD
  • java系统运维:使用java自带的工具监控系统(java)虚机的运行

    公司采用的B S架构开发的系统林林总总 有时候系统不稳定 分析起来很头疼 除了看日志 还很希望能知道系统虚拟机的运行情况 java 虚拟机从1 5开始 有类似的工具 jconsole 1 6开始不但有jconsole 还有升级版 jvisu
  • 图神经网络(一)DGL框架搭建GCN图卷积神经网络模型

    一 DGL DGL是基于pytorch开发的一个专门用于图神经网络模型搭建的框架 到现在为止 DGL已经高度封装了如GCN GraphSage GAT等常见的图神经网络模型 可以直接调用 比较方便 当然针对非常想挑战自己的编程能力又或者非常
  • 电梯系统OO设计

    理论上应该先黑盒用例 分析需要求 系统边界的输入输出 再白盒类图 但是对于现实世界模拟的OO 个人感觉先emulate现实世界 初步识别类和类之间的关系 再用用例和顺序图丰富 修正类图 识别类 最主要的原则是封装 数据和数据的操作封装成一个
  • 【Linux】ibus输入法安装教程

    My name is Linus and I am your God Linus Torvalds 安装其他输入法总是会遇到各种问题 而当新的发行版出来时 原来的输入法总是就失效了或是其他问题不能使用 经过我的多次实测 发现ibus输入法非
  • uniapp小程序实现上传图片功能,并显示上传进度

    效果图 实现方法 一 通过uni chooseMedia OBJECT 方法 拍摄或从手机相册中选择图片或视频 官方文档链接 https uniapp dcloud net cn api media video html choosemed
  • 正则表达式获取两个字符之间的字符串信息

    今天工作有一个需求就是捕获两个字符之间的字符串信息 类似就是AcakeB这个字符串中提取cake 当时只想到如下的表达式 A B 复制代码 上述是将以A开头和以B结尾的字符串提取出来 但是本意是不想要有A和B了 通过查资料发现了如下写法 l
  • JSP四大作用域

    一 ServletContext 1 生命周期 当Web应用被加载进容器时创建代表整个web应用的ServletContext对象 当服务器关闭或Web应用被移除时 ServletContext对象跟着销毁 2 作用范围 整个Web应用 3
  • sql两张表统计求比分比。

    数据 表一 compay 表二person 第一步 第一张表统计结果 select sum money from person 第二张表统计结果 select sum money from compay 相除结果 select select
  • 读取word中表格的数据

    在pro文件中加入 QT axcontainer 按步骤 1 创建Word应用程序对象 2 获取文档集 3 打开文档 4 获取活动表格 5 读取表格中的信息 QAxObject myword new QAxObject Word Appli
  • 区块链-技术简介(*)

    1 什么是区块链 区块链技术是利用块链式数据结构来验证与存储数据 利用分布式节点共识算法来生成和更新数据 利用密码学的方式保证数据传输和访问的安全 利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式 简单
  • PTA(Basic Level) 1029_旧键盘 Python实现

    1029 旧键盘 Python实现 下面是题目信息 旧键盘上坏了几个键 于是在敲一段文字的时候 对应的字符就不会出现 现在给出应该输入的一段文字 以及实际被输入的文字 请你列出肯定坏掉的那些键 输入格式 输入在 2 行中分别给出应该输入的文
  • 【AI PC端算法优化】二,一步步优化自然饱和度算法

    上一节的RGB转灰度图算法我又做了两个相关优化 加入了多线程以及去掉了上次SSE计算中的一些重复计算 现在相对于传统实现已经可以获得4倍加速 同时我也在做一个AVX2的优化 所以不久后我将发布一个RGB转灰度图算法优化的升级版 尝试触摸这一
  • 华为手机上的网上邻居怎么用_华为手机如何无线连接电脑

    不少朋友都会使用手机作为猫无线上网 那你知道如何用华为手机连接电脑3G上网 下面是小编给大家整理的一些有关华为手机连接电脑的方法 希望对大家有帮助 华为手机连接电脑的方法首先要确保已经安装了华为手机的驱动 接着在电脑的网上邻居那里点击右键
  • 浅谈对集群、分布式、分布式集群、微服务的理解

    我认为集群是个物理形态 分布式是个工作方式 分布式其实也是物理形态 这里相比较而言的 当集群中的服务器都做同样的事情时 集群就是一个集群 当集群中的服务器各司其职时 他就变成了分布式 所以说分布式中的每一个节点都可以是集群 但是集群并不一定
  • ES6的迭代器与迭代协议Symbol.iterator

    前言 ES6新增了两个协议 可迭代协议 对象必须具有Symbol Iterator属性 属性值为一个函数 当这个对象被迭代时 就会调用该函数 返回一个迭代器 迭代器协议 描述了迭代器对象的具体规则 迭代器 迭代器 它是用于访问集合类的标准访