说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

【探秘ES6】系列专栏:迭代器和for-of循环

HTML文档下载 WORD文档下载 PDF文档下载
新一代JavaScript标准,ES6即将发布。【探秘ES6】系列专栏将一一剖析ES6的诸多新特性,让Web开发者对此有清晰全面的了解。本文为系列的第二篇,带你了解ES6的迭代器和for-of循环。

ES6作为新一代JavaScript标准,即将与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系列进行翻译,供大家学习借鉴。本文为该系列的第二篇。

你是如何遍历数组中的元素的?20年前JavaScript刚进入视野时,你应该是这样写的:

for (var index = 0; index < myArray.length; index++) {     console.log(myArray[index]); }

直到ES5中原生JavaScript中添加了forEach方法:

myArray.forEach(function (value) {     console.log(value); });

语法上简洁了一些,但是它有一个小小的不足:你不能用break语句跳出循环且不能在这个封闭的函数内使用return语句。

如果有一个简单的for-loop语法来遍历数组就好了。

使用一个for-in循环怎么样?

for (var index in myArray) {     // don't actually do this     console.log(myArray[index]); }

我用几个理由来说明这并不是一个好主意:

  • 数组的索引值index是String类型的“0”,“1”,“2”等等,而不是Number类型。当你进行算术运算时(“2”+1==“21”)也许并不是你期望的结果,所以运算前需要类型转换,这很不方便。
  • 循环体不仅会遍历数组的元素,甚至连expando属性也遍历出来了。举个例子,如果你的myArray数组中有一个叫做name的属性,遍历时就将 index ==”name”也遍历出来,这样就多了一次执行。即时这些属性在数组的原型链上是可直接访问的。
  • 最让人无语的是,在某些情况下,这段代码在遍历数组元素时顺序是任意的。

总而言之,for-in语法是被设计来遍历普通的“键值对”对象的,不适合用在数组上。

强大的for-of循环

还记得我上篇提到的ES6是向后兼容的吗。即使在遍历数组的时候,成千上万的网站使用了for-in循环。所有“修复”for-in让它更适用于数组是有必要的。ES6来解决这个问题的唯一途径是新增一个新的遍历语法。

新语法如下:

for (var value of myArray) {     console.log(value); }

恩?!从构建上来说好像并没什么改变,事实如此吗?当然不是,我们来看看for-of的葫芦里究竟卖的什么药。首先,只需要注意这几点:

  • 这是目前遍历数组最简洁和直接的语法;
  • 它避免了for-in的所有缺陷;
  • 与forEach()不一样,它支持break,continue和return。

for-in循环用于遍历对象属性。

for-of循环用于遍历数据——比如数组中单值。

其它集合也支持for-of

for-of循环不仅仅是为遍历数组而设计的。基本上所有类数组对象都适用,比如DOM NodeListS。

也能用在字符串上,它将字符串当做一个Unicode字符序列:


它也能用在Map和Set对象上。

哦,不好意思,你没听说过Map和Set?没关系,他们是出现在ES6中的新成员。有机会我们会写个完整的关于它的文章。如果你使用过其它编程语言中的maps和sets,那么你也不会有陌生感。

例如,一个set对象使用于排除重复项:

// make a set from an array of words var uniqueWords = new Set(words);

如果你想遍历你的set,很简单:

for (var word of uniqueWords) {     console.log(word); }

Map有一点不同:它里面的数据由键值对组成,所以你需要使用destructuring将“键”和“值”解构为两个独立的变量:

for (var [key, value] of phoneBookMap) {     console.log(key + "'s phone number is: " + value); }

Destructuring(解构)也是ES6的新特性,在未来博客中会有很多关于它的文章。

目前为止,你可以这样理解:JS已经有了几个不同的集合类,而且更多的集合类正在被添加进来。for-of循环语句的设计初衷就是适用于所有这些集合类。

for-of并不能用于普通的旧对象。如果你想要遍历对象的所有属性,可以使用for-in,也可以通过Object.keys(object)将对象的所有属性以数组形式返回后再使用for-of。 

// dump an object's own enumerable properties to the console for (var key of Object.keys(someObject)) { console.log(key + ": " + someObject[key]); }

深入理解

“能工摹形,巧匠窃意。”——巴勃罗·毕加索

JavaScript在ES6中所新增的特性并不是凭空而来,大多数都是借鉴于其它优秀的语言。

以for-of循环伪例,与C++、Java、C#和Python的循环语句非常类似。和它们一样,支持该种语言提供的多种数据解构和标准库。但是它也是该种语言的一个扩展点。

就像for/foreach语句在其它语言中一样,for-of的执行完全靠方法调用。像Arrays,Maps,Sets等我们提到过的对象都有一个共同点就是它们都有一个遍历的方法。

其它类型的对象也都可有一个遍历方法:任何对象都可以。

就像你可以对任何一个对象添加方法myObject.toString()让JS知道如何将对象转换为字符串一样,你也可以对任何对象添加方法myObject.toString()来告诉JS如何遍历这个对象。

例如,假设你使用的jQuery,尽管喜欢使用.each(),那你也会喜欢上在jQuery对象中使用for-of。请看下面这个例子:

// Since jQuery objects are array-like, // give them the same iterator method Arrays have jQuery.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

好吧,我知道你会觉得[Symbol.iterator] 这样的语法看起来很奇怪。它是怎么执行的呢?使用方法名就可以了。标准委员会刚刚将这个方法命名为.iterator(),但是你已存在的代码中可能已经有了叫做.iterator的方法,那会造成命名冲突,让人傻傻分不清。因此所有标准库将其封装进了symbol,而不是使用简单的用字符串来直接命名。

Symbols是ES6的新特性,我们将在以后的博客中讨论它。目前,你所需要知道的是现在标准定义了一个全新的symbol,比如Symbol.iterator,为了保证与已存在的代码不存在命名冲突,所以这个代价就是语法看起来有点奇怪。

为了这个优秀的新特性的向后兼容性,这点小代价也就微不足道了。

迭代器对象

从现在开始你再也没有必要为自己写一个迭代器对象了,这个我们在下篇文章中再来讨论。但是出于完整性的考虑,让我们先来看看一个迭代器对象是什么样子的。(如果你跳过这一节,你会错过很多有趣的技术细节哟)。

for-of循环开始于对集合的[Symbol.iterator]()方法的调用。它会返回一个新的迭代器对象。任意一个有.next()方法的对象都可以被称作迭代器对象;每次执行进入循环时,for-of方法将会用.next()方法。例如,下面是一个我所能想到的最简单的迭代器构造:

var zeroesForeverIterator = {   [Symbol.iterator]: function () {       return this;    },    next: function () {        return {done: false, value: 0};    } };

每次当.next()方法被调用的时候,它会返回相同的结果,告诉for-of循环:(1)我们还没结束迭代;(2)下一个值是0。这意味着,(value of zeroesForeverIterator) {}将是一个无线循环。当然,一个真正的迭代器并不会这么简单。

迭代器的设计,伴随着.done和.value属性,从表面上来看似乎和其它语言中的迭代器不太一样。在Java中,迭代器将.hasNext()和.next()区分为两个方法。在Python中,它只有一个.next()方法,当没有下一个值时会抛出StopIteration 。但是从根本上来说,这三种方法返回同样的信息。

迭代器也可以实现一些可选方法,比如.return()和throw(ext)。在for-of循环中,当遇到异常或者break和return语句时可以调用.return()方法提前退出循环。迭代器可以通过实现.return()方法来清空变量或释放当前资源,大多数迭代器对象是使用不到这一点的。.throw(exc)是一个特殊的例子:for-of完全使用不到它,我们下次再来讨论。

现在我们已经了解了所有的基本细节,我们可以写一个简单的循环并重写它的底层方法调用部分。

先写一个for-of循环:

for (VAR of ITERABLE) {     STATEMENTS }

下面这段代码使用简单的底层方法和几个简单的变量来实现同样的功能:

var $iterator = ITERABLE[Symbol.iterator]();var $result = $iterator.next();while (!$result.done) {  VAR = $result.value;  STATEMENTS  $result = $iterator.next();}

这段代码并没有体现出.return()操作。我们可以添加进来,但是我认为认清它的执行过程比阐明它更重要。for-of的使用起来很简单,但有很多看不见幕后的工作。

我什么时候才能使用它?

当前所有的Firefox releases版本都支持for-of循环。如果你想在Chrome中使用,到chrome://flags设置“Experimental JavaScript”为“开启”即可。微软的Spartan浏览器支持它,但是IE不支持。如果你想要在Web中使用这些新语法且不用考虑支持IE和Safari,你可以使用Babel或者谷歌的Traceur这样的编译器将你的ES6代码转换成兼容性友好的ES5。

在服务端,你不需要一个编译器——你可以在io.js(基于Node,是一个不错的选择)中使用for-of。

(更新:在Chrome中默认是禁用的,这个被我忽视掉了,感谢Oleg 指出。)

讲完啦!

我们今天的计划都完成了,但是我们对for-of循环的学习还没结束。

ES6中还有一个和for-of完美结合的新对象。我之所以没提到它是因为它是我们下次的主题。

我认为它是ES6中最神奇的新特性。如果你之前没在像Python和C#这样的语言中使用过它,一开始它可能会让你感到难以置信。无论在客户端还是服务端,这是写一个构造器最简单方法,对于重构很有用,它有可能会改变我们写异步代码的方式习惯。

下次将一起深入ES6的generators 。(译者:向渝 责编:陈秋歌)

原文链接:ES6 In Depth: Iterators and the for-of loop

本译文遵循Creative Commons Attribution Share-Alike License v3.0 

相关阅读:

【探秘ES6】系列专栏:ES6简介

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。  

用VB设计更好的用户界面 用VB设计聚焦框程序 用VB实现“ICQ”式的启动欢迎画面 用VB实现全屏幕图形界面及动态功能提示 用VB实现任务栏右下角的小图标 用VB制作常居上层的浮动工具箱 用VB制作即时动态按钮 用VB作浮动式图标提示按钮 用Visual Basic编写托盘程序 用Visual Basic窗体背景花纹的实现 用Visual Basic设计窗体背景花纹 用Visual Basic设计更好的用户界面 用Visual Basic设计三维图形按钮 用VisualBasic制作半透明窗体 运行时改变控件大小的两种方法-VB资料 运行中隐藏/显示窗口标题栏-VB资料 在ListBox适当设定水平滚动条的宽度-VB资料 在VB中利用API实现窗体的平滑显示 在vb中让控件大小和位置随着表单的大小成比例变化的方法 在VB中实现闪动标题栏 在VB中实现位图的透明放置 在VB中使用数据窗体设计器插件 在VB中制作单独程序封面的两种方法 在VB中制作透明按钮 在Visual Basic中如何拖动窗体或控件 在Visual Basic中显示动态运行进度 在菜单中加入图标 -VB资料 在程序中调用关闭Windows对话框-VB资料 在任务栏中显示无边框窗体的图标-VB资料 在系统菜单上添加自定义菜单项 -VB资料 在运行时动态生成多个相同的控件?-VB资料 我现在想学一门新技术,不知道是学VC++,JAVA,还是刚刚出来的。NET技术呢?请高手指点呀。 高分征解:一个动态提示窗口的问题,给出答案必定给分!!!求救我啊!! 在这里赚分真不容易呀! 怎样检查FORM中CHECKBOX和RADIO的值呢 那里有在asp中操作word对象的详细教程? 请问:如何得到TForm的窗口句柄? authorware中的按钮。 哪里有发送mail成功的php程序!! 关于上传数据的一个特殊问题,有点难 怎么用OLE实现与手机的通讯?? 汉语分词算法 grid显示问题 成为Delphi高手须看哪方面的书籍,请高高手指教? 关于属性页的小问题? 为水园增加点正气: 大家都是斯文人吗,呵呵||||| 诗经国风2001版----之桃夭 高手高手教教我 +++++++++++++一个很奇怪的问题************* 请问:有没有专门介绍C++函数使用的书籍? 提個有點難度的問題.看問題的有獎. 高手请看:这语句错在哪? 哪儿有dos的原代码? 谁能平息这几天水园的争端^^^^^^^^^^一个详和的水园^^^^^^^^^^^我只能拿分支持 为何显示黑乎乎的一片,chick!!!!!!! 原来女人也好色,欢迎MM。 心芯蕊~来拿分~~~~MM要分能不给吗??砸锅卖铁也要给啊!~~~~55555,可怜我的分啊~~~~~~~~~~~ 着急??一小段代码!!谁来看一下?? 男子汉说到做到,我在此特地向一位女士道歉 高分求救!急急! ! ! ! 奇怪,编译DIRECTX例子正常,新建一工程后改写主文件后运行BltFast函数为何这样? 急求高人!不简单:关于common dialogbox控件的问题? 怎样学可视化编程? 用Jmail收信后,为什么WORD之类的附件打开总是乱码?? 请问如何使用BCB中的PageControl创建Wizard? 别人跟的帖子也应该能回复呀! Rational Rose2000 Enterprise Edition的License Key是什么? 哪位好兄弟肯给我一个Jbuilder4的序列号? 就有两个月了,还没怎么看书,不知道能不能过高程!!! -------我和我MM系列(转)几乎是完全版 有MM和没MM的都来看看吧 当然MM也可以看~~ 建议:在此开设一个程序之家聊天室。 请教一个简单问题!! 请问各位:如何显示GIF图像??? 最近水园很没劲,看样子是要离开的时候了,虽然我来的时间不是很长。唉,为什么会这样? 这几天晚上我都会在263战网 谁能 提供超大空间 用于上传PB80光盘 月末,大富翁银行将作月结,如果跟本银行还有业务关系,速来通知 用ado怎么连接excel文件,不用odbc行吗? 软驱自动保存是怎么一回事情 请问各位大虾,在VB中,怎样才能改变PictureBox或Imagebox的形状,让它可以容纳圆形的图片.或者用其它方法实现对不规则图片的操作.比如我编了个网络象棋程序,怎样用一个PictureBox来容纳一个圆形的棋子. 请大家帮忙一下拉。http://www.csdn.net/expert/topic/216/216983.shtm 我真急啊 有知道 MPG4 格式的吗?告诉网址也给分!!! 用SDK调用数据库?? k2cr2o7+naoh 颜色为什么不发生明显变化 _K2Cr2O7+_H2SO4+_FeSO4=>_Fe2(SO4)3+_K2SO4+_Cr2(SO4)3+_H2O HNO3电子式怎么写? h2so4环境下,k2cr2o7氧化h2o2颜色变化过程我做实验时逐滴加入H2O2,溶液先变暗绿色,渐变成亮绿色.应该是三价铬吧?为什么会不同颜色? C+K2Cr2O7+H2SO4 ------ CO2+Cr2(SO4)3+K2SO4+H2O 配平 硝酸的电子式是啥呀? 为什么K2Cr2O7,KMnO4颜色比CuSO4,FeCl3等深得多?(K2MnO4的灰绿色颜色也很深,但经不起稀释会歧化)我一浴缸水加了几粒KMnO4(不超过0.1g)结果整浴缸水都变成紫红色了K2Cr2O7,差一点,但稀释10000倍还有 K2Cr2O7+ H2C2O4+ H2SO4 — K2SO4+ Cr2(SO4)3+ CO2+ H2O HNO3的电子式怎么写? K2Cr2O7+Na2SO3生成什么 K2CR2O7在反应中得电子怎么算啊详细点 K2Cr2O7+H2C2O7+H2SO4-----K2SO4+Cr2(SO4)3+CO2+H2O求高手配平...小弟拜谢...最好带过程... 铜与硝酸反映,如果有1MOL电子,转移,则被还原的硝酸为多少A,63G B.21G C.0.5MOL D.不确定 K2Cr2O7怎么读?有奖征询,奖积分,走过看过,不要错过望各位大侠,助小女一臂之力,大恩大德,没齿难忘 Cr,K2Cr2O7,Cr2(SO4)3,CrCl2,Cr2O3,ZnCrO4这六种物质中铬元素显化合价的有哪些?请说明理由, 镁和稀硝酸反应时,每有1molHNO3反应,就有0.8mol电子转移,此时硝酸的还原产物可能是 化学问题K2Cr2O7读什么?2和7都是下标 与K2Cr2O7的Cr的化合价相同的氯化物的化学式是什么 如图,已知A、B、C三点不共线,求作一点P,使PA=PB=PC. 高中化学.k2cr2o7怎么念?了 KMnO4求化合价Mn 怎么用excel完成数据的计算机处理文件.要求有数据的点线图及数据拟合(线性或非线性提交一份用excel或origin完成的你在无机分析、物化、有机实验课所得数据的计算机处理文件.要求有数据 化学方程式配平:()K2Cr2O7+()Fe3O4+()H2SO4 与K2CR2O7中的CR的化合价相同的氧化物化学式 KClO3与HCl的反应方程式一共有几个方程式啊?还有KClO3+6HCl=KCl+3Cl2(g)+3H2O这个反应为什么Cl2既是氧化产物又是还原产物啊?用归中反应规律解释一下力求浅显谢谢!(主要是后一问) K2Cr2O7+H2SO4+(NH)2Fe(SO4)2-->请帮忙完成反应方程式并配平 如SO4 CO3 NO3 PO4 CLO3 SO3 这类是否有方法记忆其化合价 背了好久还没背出举个例子就行如SO4如何记忆 kclo3和hcl反应的离子方程式是离子方程式啊,同志们啊不要给我化学方程式 配平K2Cr2O7+KI+H2SO4---K2SO4+I2+Cr2(SO4)3+H2OK2Cr2O7+KI+H2SO4---K2SO4+I2+Cr2(SO4)3+H2O OH,NO3 NH4 SO4 CO3 PO4 MnO4 ClO3 是什麼根?我只知道 MnO4 是锰酸根. KCLO3 和 浓HCL如何反应 配平 k2cr2o7 + ki + h2so4---k2so4+ cr2(so4)3+ i2+ h2o 某透明的溶液,其中只可能含有大量的K+,Cu2+,OH-,SO3 2-,Cl-,CO3 2-,HCO3 -,MnO4 -,SO4 2-①测定溶液的pH,溶液显强碱性;②取少量溶液加入稀盐酸至溶液呈酸性,产生无刺激性、能使澄清石灰水变浑浊的气 KClO3+6HCl=KCl+3Cl2↑+3H2O有0.5mol电子转移,则有几molCl2生成?多少个HCl被氧化?几mol+5价Cl被还原? 要配制浓度为0.02mol/L的K2Cr2O7溶液1L,应准确称取K2Cr2O7基准物多少克?(K=39.1,Cr=52.0,O=16)请写出计算过程. 写出下列元素及原子团的化合价 H,K,NA,Ag,O,Ca,Ba,Mg,Zn,Al,OH,SO4,CO3,NO3,NH4,PO4 kClO3+6HCl===KCl+3Cl2+3H2O 中当转移的电子数目为0.5mol时,生成的cl2的质量为多少? 例:如K2Cr2O7标准溶液浓度为0.02150mol/L,问TFe/K2Cr2O7=?g/mL?TFe/K2Cr2O7=0.007192g/mL谁能告诉我怎么解的么. CO3的化合价是多少能不能把此物质的化学名称也写出来? 已知反应:Kclo3+6HCL=KCL+3CL2+3H2O,求出被氧化和未被氧化的HCL的质量之比.具体过程或者解题思路. 怎样将0.1000的硫代硫酸钠标准溶液稀释成0.01 mol/L这是书上的解释硫代硫酸钠标准滴定液:c(Na2S2O3)=0.01mol/L。移取1000mL刚标定过的硫代硫酸钠标准溶液0.1000mol/L于100mL棕色容量瓶中,用水稀 氯酸钾化学式 已知氧化还原反应:KCLO3+6HCL=KCL+3CL2+3H2O,在反应中得到3molCL2转移的电子为:5mol. 若用a、b、c分别表示有理数a、b、c,0为原点如图所示.已知a 求氯酸钾的化学式 KCLO3和HCl方程如何配平 过程思路///为什么我配盐酸为5帮标一下电子转移方向和数目谢了 K2Cr2O7中的Cr的化合价怎么求? KClO3如何制取O2 已知KClO3+6HCl=3Cl2+KCl+3H2O中KClO3+6HCl=3Cl2+KCl+3H2O中 求出电子如何转移转移的数目方向 求出氧化产物和还原产物的质量之比求出被氧化和未被氧化的盐酸质量之比 重铬酸钾(K2Cr2O7)中铬元素(Cr)的化合价明天就要考试了... 如何做电子密度差分图求答案 KClO3+6HCl=KCl+3Cl2+3H2O中转移电子为何为5e-与计量数是否有关? k2cr2o7与k2cro4的氧化性谁强? K2Cr2O7 铬元素的化合价是多少 N2H4电子式为什么是这样~看我画的图我知道上面一个图画掉了2个点~ 为什么N最外层只能有8个电子~ 那PCL5 里面P最外层还不是有10个 试比较KMNO4,MNO2,O2氧化性如何进行比较的呢 12个Na2So3恰好与4个K2Cr2O7完全反应,则元素Cr在被还原的产物中的化合价为 (如图)转移电子数问题,C项为什么是转移2mol电子? k2cr2o7加硫酸颜色变 化学方程式配平K2Cr2O7+C+H2SO4→Cr2(SO4)3+K2SO4+CO2+H2OCr从+6→+3,C从0→+4 ,如果按照最小公倍数K2Cr2O7前面是4,C前面是3啊,为什么K2Cr2O7前面是2呢? pcl3的电子式,最好带图
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn