ES6的 Iterator 遍历器到底是什么?
这节课要讲的是ES6中的Iterator.
for...of为啥不遍历Object对象
第十三节我们讲了简单又实用的for...of,我们可以使用它来遍历数组,字符串,Set和Map结构,但是有没有发现,我们并没有说它可以遍历Object对象,为什么不试试用它来遍历Object对象呢?
我们试试看:
//定义一个的Object对象
let obj = {"name":"前端君"}; //咱们来for...of一下
for(let v of obj){
console.log(v);
}
//结果:报错
//错误提示:obj[Symbol.iterator]不是一个function
oh no,程序报错了,for...of根本不支持遍历普通的Object对象,还出现了错误提示:**obj[Symbol.iterator]不是一个function,**这是什么鬼?
为什么数组,Set和Map结构又可以支持for...of的遍历呢?
原来,要想能够被for...of正常遍历的,都需要实现一个遍历器Iterator。而数组,Set和Map结构,早就内置好了遍历器Iterator(又叫迭代器),它们的原型中都有一个Symbol.iterator方法;而Object对象并没有实现这个接口,使得它无法被for...of遍历。
那么,我们就亲自来验证一下,它们的原型中到底是不是有个叫Symbol.iterator的方法:
//数组
Array.prototype[Symbol.iterator];
//结果:function values(){...} //字符串
String.prototype[Symbol.iterator];
//结果:function [Symbol.iterator](){...} //Set结构
Set.prototype[Symbol.iterator];
//结果:function values(){...} //Map结构
Map.prototype[Symbol.iterator];
//结果:function entries(){...} //Object对象
Object.prototype[Symbol.iterator];
//结果:undefined
从上往下看,确实,唯独Object对象的原型上没有Symbol.iterator,返回了:undefined。其他的数据类型的原型上都含有一个名字叫Symbol.iterator的方法Function。
注意:Symbol.iterator 是Symbol 对象的 iterator 属性,是一个特殊的Symbol值,因此,**当它作为prototype对象属性名的时候,获取它的时候需要使用[ ]的形式: prototype[Symbol.iterator],不能使用点形式获取:prototype.Symbol.iterator。**原因是点形式会把后面的值当作是字符串类型处理,而不是Symbol类型。第十一节有介绍,点击查看。
也就说,只要一个数据结构拥有一个叫[Symbol.iterator]()方法的数据结构,就可以被for...of遍历,我们称之为:可遍历对象。比如:数组,字符串,Set和Map结构。
现在你该知道为什么文章第一个案例会出现错误提示:obj[Symbol.iterator]不是一个function 了吧,因为Object对象的原型上压根就没有[Symbol.iterator]() 方法啊。还打算报警吗?
既然我们知道拥有[Symbol.iterator]()方法就可以被遍历,我们就会好奇:[Symbol.iterator]方法到底做了什么这么牛逼,它的原理是什么?
Iterator遍历器的原理
当可遍历对象被for...of遍历的时候,[Symbol.iterator]()就会被调用,返回一个iterator对象。其中还有一个很重要的方法:next( );
//数组:一个可遍历对象
let arr = ['a','b','c'];
//调用数组的Symbol.iterator()方法
let iter = arr[Symbol.iterator](); iter.next();
//结果:{value: "a", done: false} iter.next();
//结果:{value: "b", done: false} iter.next();
//结果:{value: "c", done: false} iter.next();
//结果:{value: undefined, done: true}
第1次调用next( )方法:返回数组的第1个元素:“a”,以及done的值为fasle,表示循环没有结束,继续遍历。
第2次调用next( )方法:返回数组的第2个元素:“b”,以及done的值还是为fasle,表示循环没有结束,继续遍历。
第3次调用next( )方法:返回数组的第3个元素:“c”,以及done的值依然为fasle,表示循环没有结束,继续遍历。
第4次调用next( )方法:返回的value值为undefined,以及done的值变成了true,表示遍历结束。
原来,for...of的原理就是:先调用可遍历对象的[Symbol.iterator]( )方法,得到一个iterator遍历器对象,然后就在遍历器上不断调用next( )方法,直到done的值为true的时候,就表示遍历完成结束了。
自定义Iterator遍历器
既然有了[Symbol.iterator]()方法就算是可遍历对象,那么我给Object对象手动加上一个[Symbol.iterator]()方法,那么它是不是可以被for...of遍历了?
那我们就试试看,给一个Object对象加一个[Symbol.iterator]( )方法,看它是不是就能被for...of遍历了?
//定义一个的Object对象
let obj = {
0:"我是0",
1:"我是1",
2:"我是2",
length:3,
//添加[Symbol.iterator]方法
[Symbol.iterator] : function() {
let _this = this;
let index = 0;
return {
next:() => {
let value = _this[index];
let done = (index >= _this.length);
index++;
return {value,done}
}
}
}
}; //咱们来for...of一下
for(let v of obj){
console.log(v);
}
//结果:"我是0"
// "我是1"
// "我是2"
上面这个案例也许你看了觉得很复杂,没看懂,没关系,我一起来分析它的结构就够了!
我们定义了一个Object对象,同时给它添加了[Symbol.iterator]()方法,并在[Symbol.iterator]()方法实现了next( )方法,next( )方法返回的对象包含了value属性和done属性。
具体细节如果不理解没关系,我们确实看到了给Object对象加上了[Symbol.iterator]()方法后,最后确实能被for...of遍历了。
这就是说,我们可以创建一个可遍历的对象,并且自定义它的遍历行为。或者说可以通过添加[Symbol.iterator]()方法,把一个不可遍历的Object对象,变成可遍历的对象。
Iterator遍历器的价值
新特性for...of之所以能够遍历各种不同的数据结构,正是因为这个数据结构都实现了Iterator遍历器接口,供for...of遍历。如果没有实现Iterator接口,则该数据结构无法被for...of遍历,比如:普通的Object对象。
本节小结
总结:Iterator遍历器为各种数据结构提供一个统一的遍历接口,使得for...of能够轻松简便地访问数据成员。 数据结构实现了Iterator接口,我们称之为可遍历对象。我们也可以自己创建可遍历对象并自定义遍历行为。
更多学习内容和干货请参考我的视频-我的空间
更多前端学习内容文章干货请关注我的专栏(不断更新)
阿里名厂标准web前端高级工程师教程目录大全,从基础到进阶,看完保证您的薪资上升一个台阶
在这里我给大家准备了很多的学习资料
其实你与阿里工程师的差距只差这些东西
明天我会拼了命的更新,加油!
ES6的 Iterator 遍历器到底是什么?的更多相关文章
- ES6的Iterator遍历器
JS表示集合的对象主要有Array.Set.Object.Map,在以前,遍历它们需要使用2种不同的方法,而现在,JS提出了Iterator机制,可以给不同的数据结构提供统一的遍历方法,就是for…o ...
- 疑问:Iterator 遍历器和数据集合各种遍历方法的区别
https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...
- Java SE之For增强与Iterator遍历器提取数据(附Map.Entry)
增强for循环: 1.操作数组 2.操作List集合 3.操作Map集合 1.map.values()法 2.map.keySet()法 [传统方法] 3.Map.Entry法 ...
- 【前端】【javascript】es6中的遍历器接口Iterator
好久没发文章啦-.-为了证明我还活着,我决定从笔记里面抓一篇还算不乱比较像文章的发出来... 这些笔记是我在学es6的时候断断续续记录的,最近会一份一份整理陆陆续续发出来,顺便也自己再看一遍.我学习e ...
- ES6学习笔记(十三)Iterator遍历器和for...of循环
1.概念 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有 ...
- Iterator 遍历器
1.遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员). 2.Iterator ...
- Iterator遍历器 调用Symbol.Iterator属性,遍历器对象。
Iterator实现原理 创建一个指针对象,指向当前数据结构的起始位置.也就是说,遍历器对象本质上,就是一个指针对象. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员. 第二次调 ...
- generator生成器iterator遍历器和yield
generator方法()返回一个iterator 使用generator时永远先去调用generator()方法 for of对iterator的调用过程(babel参照) 1,_iterator. ...
- Iterator(遍历器) 和 for...of 循环
是generator的前置知识 generator :https://www.cnblogs.com/wangtong111/p/11322961.html 遍历器(Iterator)就是这样一种机制 ...
随机推荐
- SpringCloud服务的注册发现--------Eureka实现高可用
1,Eureka作为注册中心,掌管者服务治理的功能,十分重要,如果注册中心的服务一旦宕机,所有的服务就会挂了,为此,实现注册中心的集群(高可用)就显得十分必要了 2,Eureka 搭建集群 实现原理就 ...
- BurpSuit工具安装和基本使用方法
burpsuite是渗透的必备工具,使用它可以进行一些截包分析,修改包数据.暴力破解.扫描等功能,使用最多的场景应该是设置代理拦截数据包分析数据和爆破. JDK工具下载和安装(可选) 运行BurpSu ...
- spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(01)
在spring中beanPostProcessor绝对是开天辟地的产物,给了程序员很多自主权,beanPostProcessor即常说的bean后置处理器. 一.概览 先来说下Instantiatio ...
- 关于visocode 自动保存时自动添加分号问题
先下载插件: Vueter 打开设置的配置文件,写入一下代码: // //是否需要保存时自动格式化 "editor.formatOnSave": true, //使js 文件保存 ...
- Aircoinst 三层架构ASP.NET开源
<注意! 本源码为我本人所写,可能有点烂.仅供学习使用,请勿进行商业用途~!> <本源码永久归于MineLSG 及 Aircoinst_慈 所拥有> 使用方法:直接拷贝 一.结 ...
- Bitmap之位图采样和内存计算详解
原文首发于微信公众号:躬行之(jzman-blog) Android 开发中经常考虑的一个问题就是 OOM(Out Of Memory),也就是内存溢出,一方面大量加载图片时有可能出现 OOM, 通过 ...
- oracle实现分页功能 limit功能例子
oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum并不是用户添加的字段,而是oracle系统自动添加的. 记录两种常用方法: (1)使查询 ...
- 从谷歌 GFS 架构设计聊开去
伟人说:“人多力量大.” 尼古拉斯赵四说:“没有什么事,是一顿饭解决不了的!!!如果有,那就两顿.” 研发说:“需求太多,人手不够.” 专家说:“人手不够,那就协调资源,攒人头.” 释义:一人拾柴火不 ...
- Window.requestAnimationFrame()动画更新
概述 Window.requestAnimationFrame()方法告诉浏览器你希望执行动画,并且再下一次重绘之前要求浏览器调用一个特定的函数去更新动画.该方法把一个回调函数作为参数,该回调函数会在 ...
- scratch 如何改变变量的作用域
在新建变量的时候,有个选项是“适用于所有角色”还是“仅适用于当前角色”.通常称前者为全局变量,所有角色都可以访问到这个变量:后者,称为局部变量,只能在当前角色里访问到这个变量.例如,在使用克隆功能时, ...