ES6 - Iterator迭代器和for...of 循环

在这里插入图片描述

文章目录

    • 前言
    • 一、Iterator介绍
    • 二、Iterator原理
    • 三、实现Iterator接口的原生对象有
    • 五、默认调用 Iterator 接口的场合
    • 六,for... of 循环
    • 七,总结

前言

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

一、Iterator介绍

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

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

二、Iterator原理

Iterator直接翻译是迭代器 他能够迭代出任何可迭代数据类型中的数据,为可迭代数据提供一个接口机制 能够迭代出数据;

一般情况下 :迭代数据使用函数的next方法,如果说数据存在 那么返回对象{value :数据, done : false}

如果说 :没有数据了 那么返回对象:{value : undefined , done : true}

所以说 我们使用iterator之前 要先定义一个指针, 指针是为了指向数据从哪开始迭代;最开始 指针的指向是第0个元素;

如下面的案例:


function makeIterator(array) {var nextIndex = 0;return { // 注意:此处使用了闭包,nextIndex会被一直引用,也就是会被下面一直累加;next: function() {// 注意:此处判断结束条件  当前长度是否小于数组的总长度// 小于说明未运行结束  不小于说明改结束了return nextIndex < array.length ?{value: array[nextIndex++], done: false} :{value: undefined, done: true};}};
}var it = makeIterator(['a', 'b']);it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

Iterator 的遍历过程是这样的:

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

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

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

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

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

三、实现Iterator接口的原生对象有

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性上;或者说,一个数据结构只要有Symbol.iterator属性,就认为是可遍历的。

原生具备Iterator接口的数据结构有:

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

可以看到Array原型对象和Set集合已经实现了Iterator这个属性:

  // 数组console.log("array:",Array.prototype);// Es6新增Set集合let set = new Set([1, 2, 3]);console.log("set:",set);

打印如下图:
在这里插入图片描述
那么数组的实例对象当然也会拥有这个属性,如下:

      let arrIter = [1, 2, 3][Symbol.iterator]();console.log("arrIter:", arrIter);console.log(arrIter.next());console.log(arrIter.next());console.log(arrIter.next());console.log(arrIter.next());

在这里插入图片描述

五、默认调用 Iterator 接口的场合

有一些场合会默认调用 Iterator 接口(即Symbol.iterator方法),除了下文会介绍的for...of循环,还有几个别的场合。

(1)解构赋值

对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法。

let set = new Set().add('a').add('b').add('c');let [x,y] = set;
// x='a'; y='b'let [first, ...rest] = set;
// first='a'; rest=['b','c'];

(2)扩展运算符

扩展运算符(…)也会调用默认的 Iterator 接口。

// 例一
var str = 'hello';
[...str] //  ['h','e','l','l','o']// 例二
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']

实际上,这提供了一种简便机制,可以将任何部署了 Iterator 接口的数据结构,转为数组。也就是说,只要某个数据结构部署了 Iterator 接口,就可以对它使用扩展运算符,将其转为数组。

let arr = [...iterable];

(3)yield*

yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

let generator = function* () {yield 1;yield* [2,3,4];yield 5;
};var iterator = generator();iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }

(4)其他场合

由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。下面是一些例子。

  • for…of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]])
  • Promise.all()
  • Promise.race()

六,for… of 循环

for... of循环其实就是 Iterator 的语法糖

for…of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、字符串等。也就是说有Iterator 接口的数据类型,for …of 都可以遍历;

(不能遍历普通对象,会直接报错,obj is not iterable)

数组原生具备iterator接口,(默认部署Symbol.iterator属性),for...of 循环本质上就是调用这个接口产生的遍历器:

for…of 使用如下:

      ## 1,遍历数组 let arr = [{name:'Eula',age:20},{name:'Kaya',age:20}]for (const iterator of arr) {console.log("iterator:",iterator); // {name: 'Eula', age: 20}  {name: 'Kaya', age: 20}}## 2,遍历字符串 let str = "hello"for (const iterator of str) {console.log("iterator:",iterator); // 'h' 'e' 'l'' l'' o'}## 3,遍历set集合let set = new Set([{name:'Eula',age:20},{name:'Kaya',age:20}])for (const iterator of set) {console.log("iterator:",iterator); // {name: 'Eula', age: 20}  {name: 'Kaya', age: 20}}## 4,遍历map集合let map = new Map()map.set('name','Eula')map.set('age','18')console.log("map:",map); // Map(2) {'name' => 'Eula', 'age' => '18'}for (const iterator of map) {console.log("iterator:",iterator); //  ['name', 'Eula']  ['age', '18']}

如果想要遍历普通对象可以使用 for in 循环:

      let obj = {name:'Eula'}for (const iterator in obj) {console.log("键:",iterator); // nameconsole.log("值:",obj[iterator]);  // Eula}

七,总结

  1. 一个数据结构的原型上只要有Symbol.iterator属性,就认为是可遍历的。
  2. for… of循环其实就是 Iterator 的语法糖。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt Creator 11 开放源码集成开发环境新增集成终端和 GitHub Copilot 支持

导读Qt 项目今天发布了 Qt Creator 11&#xff0c;这是一款开源、免费、跨平台 IDE&#xff08;集成开发环境&#xff09;软件的最新稳定版本&#xff0c;适用于 GNU/Linux、macOS 和 Windows 平台。 Qt Creator 11 的亮点包括支持标签、多外壳、颜色和字体的集成终端模拟器&am…

【微信小程序创作之路】- 小程序事件绑定、动态提示Toast、对话框 Modal

【微信小程序创作之路】- 小程序事件绑定、动态提示Toast、对话框 Modal 第六章 小程序事件绑定、动态提示Toast、对话框 Modal 文章目录 【微信小程序创作之路】- 小程序事件绑定、动态提示Toast、对话框 Modal前言一、事件是什么&#xff1f;二、小程序中常用事件三、事件传…

2023年受人欢迎的低代码开发平台大盘点

随着企业对于降低成本和加快软件开发的需求增加&#xff0c;低代码开发平台逐渐成为一种受欢迎的选择。这些平台提供了拖放界面和预置组件&#xff0c;使得开发人员可以用更少的代码创建复杂的应用软件。低代码开发平台不仅有助于企业加速数字化转型&#xff0c;而且还能打破业…

URP基于GL的Unity物体网格线绘制方法参考

直接上代码&#xff1a; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering;public class GLWireMesh : MonoBehaviour {[Serializable]public class IntPair{public int a;public int b;public IntPair(int a, int b){this.a…

Linux系统管理:虚拟机Rocky Linux安装

目录 一、理论 1.Rocky Linux 2.NetworkManager配置 3.ipaddress 配置文件 4.nmtui 配置 ipaddress 二、实验 1.虚拟机Rocky Linux安装准备阶段 2.安装Rocky Linux 3.进入系统 三、问题 1.网络配置文件权限不够 一、理论 1.Rocky Linux &#xff08;1&#xff0…

下载的谷歌模型如何转为3dtiles

收费工具&#xff0c;学生党勿扰 收费金额1000元 已经购买过工具的大佬&#xff0c;可以免费更新 1 概述 上个月&#xff0c;写了一篇<<谷歌地图模型自动下载>>的文章&#xff0c;效果还不错&#xff0c;能够帮到一些同学。 但是&#xff0c;随着谷歌模型下载的越…

uniapp开发微信小程序--自定义顶部导航栏

一、实现效果&#xff1a; 二、代码实现&#xff1a; 1.在pages.json文件中&#xff0c;单页面定义导航栏&#xff0c;添加以下代码&#xff1a; "navigationStyle": "custom" //自定义导航栏如图所示&#xff1a; 2.在components文件夹下&#xff0c;…

使用多数据源dynamic-datasource-spring-boot-starter遇到的问题记录

记录使用多数据源dynamic-datasource-spring-boot-starter遇到的问题&#xff1a; 1、工程启动失败 缺少clickhouse连接驱动&#xff0c;引入对应的maven依赖 <!--ck连接驱动--><dependency><groupId>ru.yandex.clickhouse</groupId><artifactId>…

Kylin v10基于cephadm工具离线部署ceph分布式存储

1. 环境&#xff1a; ceph&#xff1a;octopus OS&#xff1a;Kylin-Server-V10_U1-Release-Build02-20210824-GFB-x86_64、CentOS Linux release 7.9.2009 2. ceph和cephadm 2.1 ceph简介 Ceph可用于向云平台提供对象存储、块设备服务和文件系统。所有Ceph存储集群部署都从…

制作crate并发布到Crates.io

准备 发布 crate 时, 一旦发布无法修改,无法覆盖, 因此要注意邮箱等一些个人信息 访问crates.io 的 帐号设定页面[1],生成Token 并在命令行 执行 cargo login your token 此命令将告诉 Cargo 你的 API 令牌, 并将其存储在本地 ~/.cargo/credentials crates.io 上crate的名字, 会…

生成测试报告就万事大吉了吗?NO,升职加薪就差这一步啦!- 04(非常详细,非常实用)

简介 上一篇生成测试报告&#xff0c;小伙伴们和童鞋们就又问道&#xff0c;测试报告已经生成了&#xff0c;怎么发送给相关的负责人了&#xff1f;小伙伴们和童鞋们不要着急&#xff0c;慢慢给你道来&#xff0c;心急吃不了热豆腐哈。这些小伙伴们的表现还是不错的&#xff0c…

安装nvm之后,node -v 提示‘node‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

1. 检查有没有执行这个命令&#xff1a;nvm use [nodejs version name] 2. 检查nvm安装位置同级&#xff0c;有没有nodejs文件夹&#xff0c;是一个快捷键&#xff01;如果有一个其他的nodejs&#xff0c;把它删掉&#xff0c;然后到cmd中&#xff0c;重新nvm install一下&…

【计算机网络】应用层协议 -- 安全的HTTPS协议

文章目录 1. 认识HTTPS2. 使用HTTPS加密的必要性3. 常见的加密方式3.1 对称加密3.2 非对称加密3.3 非对称加密对称加密 4. 引入CA证书4.1 CA认证4.2 数据签名4.3 非对称机密对称加密证书认证4.4 常见问题 5. 总结 1. 认识HTTPS HTTPS全称为 Hyper Text Tranfer Protocol over …

API教程:轻松上手HTTP代理服务!

作为HTTP代理产品供应商&#xff0c;我们为您带来一份详细的教程&#xff0c;帮助您轻松上手使用API&#xff0c;并充分利用HTTP代理服务。无论您是开发人员、网络管理员还是普通用户&#xff0c;本教程将为您提供操作指南和代码模板&#xff0c;确保您能够顺利使用API并享受HT…

【深度学习】Inst-Inpaint: Instructing to Remove Objects with Diffusion Models,指令式图像修复

论文&#xff1a;https://arxiv.org/abs/2304.03246 code:http://instinpaint.abyildirim.com/ 文章目录 AbstractIntroductionRelated WorkDataset GenerationMethodPS Abstract 图像修复任务是指从图像中擦除不需要的像素&#xff0c;并以语义一致且逼真的方式填充它们。传统…

SQL项目实战:银行客户分析

大家好&#xff0c;本文将与大家分享一个SQL项目&#xff0c;即根据从数据集收集到的信息分析银行客户流失的可能性。这些洞察来自个人信息&#xff0c;如年龄、性别、收入和人口统计信息、银行卡类型、产品、客户信用评分以及客户在银行的服务时间长短等。对于银行而言&#x…

使用DeferredResult来设计异步接口

文章目录 DeferredResult 介绍思路Demo搭建1.定义一个抽象的请求体2.定义一个接口返回体3.定义一个接口请求体继承抽象类AsynTaskBaseRequest<T<T>>4.定义seveice类&#xff0c;并声明一个异步方法&#xff08;Async注解&#xff09;5.定义一个返回DeferredResult的…

Chrome浏览器中的vue插件devtools的下载方式(使用Chrome应用商店/科学上网情况下)

目录 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤&#xff1a; 测试阶段&#xff1a; 最近做项目要使用devtools这个vue插件。 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤…

【云原生】Serverless 技术架构分析

一、什么是Serverless? 1、Serverless技术简介 ​ Serverless&#xff08;无服务器架构&#xff09;指的是由开发者实现的服务端逻辑运行在无状态的计算容器中&#xff0c;它由事件触发&#xff0c; 完全被第三方管理&#xff0c;其业务层面的状态则被开发者使用的数据库和存…

基于小程序+spring boot流浪动物救助系统-计算机毕设 附源码12783

小程序spring boot流浪动物救助系统 摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;流浪动物救助系统被用…