ES6系列教程第二篇--Iterator 详解

2023-10-27

一、什么是for-of循环

  对于如下一个数组,遍历其中的值方法有哪些?

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

首先想到的可能就是如下这种,这也是js最原始的遍历方法,和java的语法一样。

 var arr = ['a', 'b', 'c'];
 for (var i=0;i<arr.length;i++) {
     console.log(arr[i]);
 }

如果你了解ES5,还可以写出for-in的方法。

var arr = ['a', 'b', 'c']; 
for(var i in arr){
   console.log(arr[i]);
}

今天为大家再介绍一种for-of的遍历方法

var arr = ['a', 'b', 'c']; 
for(var ch of arr){
    console.log(ch);
}

在这个例子中,大家注意到使用for-of时,ch不是数组的索引值,所示其中的value值。

那有了for-in,为什么还要设计for-of呢,或者说for-of有什么独特的地方。继续实例:

let arr = "abc";
for( var char of arr){
    console.log(char);
}

此时,可以将a,b,c输出,但是for-in是无能为力的。其中for-of不仅能对数组和字符串进行遍历。还可以适用以下的集合:

Map

Set

NodeList

其中Map,Set是ES6新增的特性,现在不了解也没关系,我们稍后单独讲。NodeList是DOM对象集合,有兴趣的可能查阅资料了解,不在这里展开讨论。

二、迭代器(Iterator)实现原理

再看一个普通的字面量对象例子:

var obj={0:"rrr",1:"444"};
   for(var value of obj){
     console.log(value);
   }

    运行后发现报错,表明这个字面量对象是不可遍历的。那能否像Array,String等对象一样支持for-of遍历呢?答案是可以的,Array,String等对象之所以可遍历,是因为在他们的原型上,实现了迭代器(Iterator)的接口。

  那如何实现迭代器(Iterator)接口呢,只需要在这个对象中实现[Symbol.iterator]属性方法,[Symbol.iterator]这个属性名ka看起来怪怪的,Symbol是ES6表示唯一性的标识符,标准委员会是为了避免命名的冲突,所以才这样命名,大家作为一个唯一的字符串理解即可,不去深究。下面我们来实现[Symbol.iterator]属性。如下:

var obj={
    0:"rrr",
    1:"444",
    //实现[Symbol.iterator]属性方法
    [Symbol.iterator]:function(){
        const self = this;
        let index=0;
        return {
          next:function(){//实现next
            if(index<2){
              return {//遍历中
                value:self[index++],
                done: false//表示遍历没有结束,done设置为fasle
              }
            }else{
              return{//遍历结束
                value:undefined,//结束后,返回undefined
                done: true//done设置为true,表示遍历结束
              }
            }
          }
        }
     } 
    };
   for(var value of obj){
     console.log(value);//"rrr","444"
   }

  此时正确的遍历了obj,打印了obj的属性的值。再来看下[Symbol.iterator]属性函数体,返回了next方法,next方法中遍历了此obj的属性对象,并返回字面量对象{value:xxx,done:xxx}这种结构对象,在遍历过程中,value返回对应属性值,且done设置为false;当遍历结束后,value返回undefined,且done设置为true。

var it = obj[Symbol.iterator]();
console.log(it.next());//{value: "rrr", done: false}
console.log(it.next());//{value: "444", done: false}
console.log(it.next());//{value: undefined, done: true}

   这就是for-of的原理,每次遍历都会调用该对象的[Symbol.iterator]属性的next方法,当返回{value: undefined, done: true}后,表示遍历结束。

所以讲到这,各位道友是否就明白了,任何对象要变成可遍历的对象,只需要实现[Symbol.iterator]属性方法,定义其中的next方法即可。

三、break,continue

  学过java的道友们,对break,continue应该再熟悉不过了,意义我就不再阐述。for-of对于for-in的优点就是它能支持这些语句。我们接着往下看。

let arr = "abc";
for( var char of arr){
      console.log(char);//"a"
      break;
}

仅输出了“a”就跳出了循环。有兴趣的道友可以再实验下continue,看看效果。

好了,我们将上面obj的实例再修改下,使其支持这些语句

var obj={
    0:"rrr",
    1:"444",
    //实现[Symbol.iterator]属性方法
    [Symbol.iterator]:function(){
        const self = this;
        let index=0;
        return {
          next:function(){//实现next
            if(index<2){
              return {//遍历中
                value:self[index++],
                done: false//表示遍历没有结束,done设置为fasle
              }
            }else{
              return{//遍历结束
                value:undefined,//结束后,返回undefined
                done: true//done设置为true,表示遍历结束
              }
            }
          },
         return:function() {//增加return,支持continue,break
          return { done: true };
        }
        }
     } 
    };
   for(var value of obj){
     console.log(value);//"rrr"
     break ;
   }

此时仅输出了"rrr"就跳出了循环,在执行break时,内部调用了return的方法,返回了{done:false},continue也是如此。

四、总结

  主要学些了for-of循环,并通过这个循环讲述了迭代器(Iterator)的实现原理。for-of的用处还是很强大的,可以和我们下一章节要介绍的Generator对象很好的结合。

上一篇:ES6系列教程第一篇--Promise详解                             下一篇:ES6系列教程第三篇--Generator 详解

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

ES6系列教程第二篇--Iterator 详解 的相关文章

随机推荐

  • AcWing 3719. 畅通工程(并查集)(天津大学考研上机)

    输入样例 4 2 1 3 4 3 输出样例 1 include
  • 装jdk

    首先从官网上下载jdk安装包 如果后缀 i586 则是32位的 大部分电脑不要选 我们要选后缀X64的 这才是64位电脑应该选的 双击jdk 一路next 装好之后 还会弹出让你安装jre 因为jdk自带jre 所以这个jre装不装都行 装
  • 【经典】SpringBoot常用基本配置

    SpringBoot支持properties文件和yml文件 两个文件同时存在 优先以properties为准 通过properties文件配置 1 基本设置 server port 80 debug true server servlet
  • 超频到3200最佳时序_如何榨取更多CPU性能:CPU BIOS超频简单教程

    你为什么要超频 以前超频是可以换来性能的大幅度提升 但是近些年来超频带来的收益其实已经大幅降低 因为不论Intel还是AMD都已经把CPU的频率拉到接近极限 留给玩家的可超频空间其实不多 性能提升已经远没有以前明显 但是依然有不少人追求超频
  • STM32单片机初学者常用函数--I2C配置

    I2C的配置必须要按照其时序逻辑 首先先来了解I2C常见的几种工作情况 A 主机向从机发送数据 数据传输方向在整个传输过程中不变 B 主机在第一个字节后 立即从从机读数据 C 在传输过程中 当需要改变传输方向时 起始信号和从机地址都被重复产
  • MATLAB卡尔曼数字滤波惯性测量单元数据(行驶距离和速度估计)

    惯性测量单元 IMU 是惯性导航系统 INS 的一个组件 惯性导航系统是一种导航设备 用于在没有外部参考的情况下计算移动物体的位置 速度和方向 该项目开发了一种方法 用于消除加速度计测量中的偏差 并估计移动物体的行进距离和速度 估计是使用卡
  • linux 服务状态命令,Linux 查看服务列表,查看服务状态

    使用service查看命令说明 ubuntu VM 0 17 ubuntu service Usage service status all service name command full restart ubuntu VM 0 17
  • ElasticSearch聚合查询返回结果buckets取值

    ElasticSearch聚合查询返回结果buckets取值 1 聚合查询如下 size 0 query bool must wildcard county company keyword wildcard 3 boost 1
  • Stm32-SysTick详解

    写在最前 本文是个人学习Stm32时所做笔记 没有写过C51 但学校学过 微机原理 但没学好 实验套件是正点原子Stm32zet6精英板 参考资料为正点原子所提供 本文所涉及代码均使用固件库 本文供自己日后需要时复习所用 同时希望可以给有需
  • 若依框架注册新用户,且赋角色

    若依框架注册新用户 且赋角色 若依官网 1 如何开启注册功能 开启前端注册开关 不管使用下那种方式开启注册功能 首先 先在前端里面views下找到login vue 将启注册开关先给设置为true 保存重启即可 如下图 2 两种开启新增用户
  • 【每日算法 && 数据结构(C++)】—— 06

    文章目录 01 题目描述 02 解题思路 03 代码片段 Time waits for no one cherish every moment 岁月不居 时光荏苒 珍惜每分每秒 01 题目描述 给你若干个有序链表 请将他们合并为一个有序的链
  • TP-LINK 路由器设置内网穿透

    TP LINK 路由器设置内网穿透 开发中经常遇到调用第三方软件回调调试的情况 例如微信开发 支付回调等测试 用内网穿透是一种简单的方式也是偷懒的方式 以TP LINK路由器为例实现内网穿透 登录路由器 2 找到路由器虚拟服务器 添加映射
  • tsconfig之forceConsistentCasingInFileNames属性

    文章来源 Wflynn forceConsistentCasingInFileNames 作用 是否强制代码中使用的模块文件名必须和文件系统中的文件名保持大小写一致 示例 假设我们有一个文件名为 FileManager ts 我们从这个文件
  • ECharts合并地图上的区域

    对于某些特定需求 官方下载的地图数据可能并不能完全满足 例如 要求显示中国地图 但需要将山东江苏和浙江这3个省合并起来 显示 东部区域 其他省份不变 于是就需要对官方提供的地图数据进行修改 一个思路是借助第三方工具 生成新区域的轮廓点 然后
  • 刷脸支付打造数字小镇应用的全新探索

    刷脸支付打造数字小镇是特色小镇数字化应用的一项全新探索 主要是依托一部手机游云南平台 在精准治理 惠民服务 生态宜居等领域进行数字化应用 丽江大研古城数字小镇启动建设以来已经取得初步成效 1月16日 从云南省发展和改革委员会举行的1月定时定
  • 28、宏任务与微任务

    原理图 setImmediate 也是宏任务 在 Node 环境下 微任务还有 process nextTick JS 中用来存储待执行回调函数的队列包含 2 个不同特定的列队 宏列队 用来保存待执行的宏任务 回调 比如 定时器回调 DOM
  • VMware Workstation 15虚拟机使用教程

    VMware Workstation 15虚拟机使用教程 前言 一 在虚拟机中安装win7 1 1新建虚拟机一个win7虚拟机 1 2插入虚拟机光盘 即指定ISO镜像文件 1 3设置虚拟机的BIOS 光驱为第一启动 1 4开始在虚拟机中安装
  • 数据库中的字段名与实体类中的属性名不能一一对应时的三种处理方式

    当查询结果的列名和java对象的属性名对应不上时需要采用下列方式进行处理 第一种方式 在查询语句中使用关键字 as 给列起别名 第二种方式 使用resultMap结果映射 第三种方式 开启驼峰命名自动映射 配置settings 实体类Car
  • Douglas-Peucker算法的Matlab实现

    代码 Douglas Peucker 道格拉斯 普克算法 function curve dpEdgeContour pnts clc clear A readmatrix EdgeContour1 xls Sheet 1 输入数据 x A
  • ES6系列教程第二篇--Iterator 详解

    一 什么是for of循环 对于如下一个数组 遍历其中的值方法有哪些 var arr a b c 首先想到的可能就是如下这种 这也是js最原始的遍历方法 和java的语法一样 var arr a b c for var i 0 i