详解ES6中的for … of循环和可迭代对象
另外,生成器函数又是什么鬼?
可迭代对象是定义了 @@ iterator 方法的对象,而且 @@iterator 方法返回一个实现了迭代器协议的对象,或者该方法是生成器函数。搞懂这些内容的最简单方法就是一步一步的去创建可迭代对象。首先,我们需要一个实现 @@iterator 方法的对象。 @@ 表示法有点误导性,我们真正??要做的是用预定义的 Symbol.iterator 符号定义方法。
for(const [key, value] of foo) { ^ TypeError: Iterator result undefined is not an object这次 javascript 告诉我们它试图调用 Symbol.iterator 方法,而该对象的确是一个对象,并且实现了 next 方法,但是 next 的返回值不是 javascript 预期的对象。
更多编程相关知识,请访问:编程视频!!
以上就是详解ES6中的for … of循环和可迭代对象的详细内容,更多请关注聚合云库其它相关文章!
[ 0, 'apples' ] [ 1, 'oranges' ] [ 2, 'pears' ]当用下面的语法时,entries 方法会更有用
class First20Evens { constructor() { this.currentValue = 0 } [Symbol.iterator]() { return { next: (function() { this.currentValue+=2 if(this.currentValue > 20) { return {done:true} } return { value:this.currentValue } }).bind(this) } } } const foo = new First20Evens; for(const value of foo) { console.log(value) }生成器手动去构建实现迭代器协议的对象不是唯一的选择。生成器对象(由生成器函数返回)也实现了迭代器协议。上面的例子用生成器构建的话看起来像这样:
迭代器协议(这里的协议是什么意思?)
@@iterator方法( @@是什么意思?)
首先是经典的 for i 循环,它使你可以遍历数组或可索引的且有 length 属性的任何对象。
const foo = [ 'apples','oranges','pears' ] for(const [key, value] of foo.entries()) { console.log(key,':',value) }在 for 循环中声明了两个变量:一个用于返回数组的第一项(值的键或索引),另一个用于第二项(该索引实际对应的值)。
next 函数需要返回有特定格式的对象——有 value 和 done 这两个键。
for(const [key, value] of foo) { ^ TypeError: Result of the Symbol.iterator method is not an object这是 javascript 告诉我们它在试图调用 Symbol.iterator 方法,但是调用的结果不是对象。
早期的 javascript 通过库解决了这个问题。许多 JavaScript库(例如:Prototype.js,jQuery,lodash 等)都有类似 each 或 foreach 这样的工具方法或函数,可让你无需 for i 或 for ... in 循环去遍历对象和数组。
在过去,有两种方法可以遍历 javascript。
在这句话中你需要理解很多东西:
for … offor ... of 循环
所以在代码中放入另一个程序,它带有一个简单的迭代器,该迭代器返回前十个偶数。
如果用迭代器方法定义对象并尝试遍历:
for(const thing of things) { /* ... */ }它将遍历一个可迭代(iterable)对象。
下面逐个解决这些疑问。
apples oranges pears还有数组的 entries 方法,它返回一个可迭代对象。这个可迭代对象在每次循环中返回键和值。例如下面的代码:
const foo = { 'apples':'oranges', 'pears':'prunes' } for(const [key, value] of Object.entries(foo)) { console.log(key,':',value) }能够得到你期望的输出:
$ node test.js apples : oranges pears : prunes创建自己的 Iterable如果你想创建自己的可迭代对象,则需要花费更多的时间。你会记得前面说过:
// 无法正常执行 const foo = { 'apples':'oranges', 'pears':'prunes' } for(const [key, value] of foo) { console.log(key,':',value) }会得到一个错误
如果 done 为 false 或不存在,则需要 value 键。 value 键是通过循环此应该返回的值。
for(key in things) { if(!thing.hasOwnProperty(key)) { continue; } var thing = things[key] /* ... */ }for ... in 循环通常被视作旁白,因为它循环了。这包括原型链中父对象的属性,以及被分配为方法的所以属性。换句话说,它遍历了一些人们可能想不到的东西。使用 for ... in 通常意味着循环块中有很多保护子句,以避免出现不需要的属性。
const foo = [ 'apples','oranges','pears' ] for(const thing of foo) { console.log(thing) }输出结果是数组中的所有元素。
内置 Iterable首先,javascript 对象中的一些内置对象天然的可以迭代,比如最容易想到的就是数组对象。可以像下面的代码中一样在 for ... of 循环中使用数组:
const foo = [ 'apples','oranges','pears' ] for(const thing of foo.entries()) { console.log(thing) }将输出以下内容
为了消除这个错误,需要用迭代器方法来返回实现了迭代器协议的对象。这意味着迭代器方法需要返回一个有 next 键的对象,而 next 键是一个函数。
for ... of 循环是 ES6 试图不用第三方库去解决其中一些问题的方式。
class First20Evens { constructor() { this.currentValue = 0 } [Symbol.iterator]() { return function*() { for(let i=1;i<=10;i++) { if(i % 2 === 0) { yield i } } }() } } const foo = new First20Evens; for(const item of foo) { console.log(item) }本文不会过多地介绍生成器,如果你需要入门的话可以看这篇文章。今天的重要收获是,我们可以使自己的 Symbol.iterator 方法返回一个生成器对象,并且该生成器对象能够在 for ... of 循环中“正常工作”。 “正常工作”是指循环能够持续的在生成器上调用 next,直到生成器停止 yield 值为止。
const foo = { [Symbol.iterator]: function() { return { next: function() { } } } } for(const [key, value] of foo) { console.log(key, value) }如果运行上面的代码,则会出现新错误。
等等,迭代(iterable)和迭代器(iterator)不是一回事?
可迭代的对象
一个普通的 javascript 对象是不可迭代的。如果你执行下面这段代码:
可迭代对象是定义了 @@ iterator 方法的对象,而且 @@iterator 方法返回一个实现了迭代器协议的对象,或者该方法是生成器函数。
$ node test.js /path/to/test.js:6 for(const [key, value] of foo) { TypeError: foo is not iterable然而全局 Object 对象的静态 entries 方法接受一个普通对象作为参数,并返回一个可迭代对象。就像这样的程序:
const foo = { [Symbol.iterator]: function() { } } for(const [key, value] of foo) { console.log(key, value) }得到一个新错误:
for(i=0;i<things.length;i++) { var thing = things[i] /* ... */ }其次是 for ... in 循环,用于循环一个对象的键/值对。
作者:Alan Storm
next: function() { //... return { done: false, value: 'next value' } }done 键是可选的。如果值为 true(表示迭代器已完成迭代),则说明迭代已结束。
$ node sample-program.js 2 4 6 8 10英文原文地址:https://alanstorm.com/es6s-many-for-loops-and-iterable-objects/
相关热词: 详解
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/jiaob/javascript/4617.shtml
相关文章
热门TAG
服务器 命令 技巧 详解 调用 标签 功能 织梦 javascript dedecms修改内容 织梦教程 php 白帽 企业网站 外链 权重 MYSQL 网站流量 实例解析 JSP 网站收录 搜索引擎 蜘蛛 windows jquery jquery教程 python tags标签 HTML 织梦cms最新文章
-
Javascript是什么?
时间:2021-01-04
-
Canvas入门实战之实现一个
时间:2021-01-04
-
11月份GitHub上最热门的Ja
时间:2021-01-04
-
一篇带给你JavaScript的Cla
时间:2021-01-04
-
详解js异步文件加载器
时间:2021-01-04
-
深入理解JavaScript中的箭头
时间:2021-01-04
-
复盘Node项目中遇到的13+常
时间:2021-01-04
-
连续3年稳居第一,全球
时间:2021-01-04
热门文章
-
连续3年稳居第一,全球1240万用户,Java
时间:2021-01-04
-
一篇带给你JavaScript的Class语法介绍
时间:2021-01-04
-
深入理解JavaScript中的箭头函数
时间:2021-01-04
-
Javascript在Chrome浏览器中调试的七个步骤
时间:2021-01-04
-
Canvas入门实战之实现一个图形验证码
时间:2021-01-04
-
详解js异步文件加载器
时间:2021-01-04
-
复盘Node项目中遇到的13+常见问题和解决方
时间:2021-01-04
-
11月份GitHub上最热门的JavaScript开源项目
时间:2021-01-04
-
Javascript是什么?
时间:2021-01-04
