摘要:本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。不过,严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作结构使用,没有结构,而原生提供了。
经常看到迭代这个词,那么归总下吧~
什么是可迭代对象:
一个对象(或它的原型链上的某个对象)必须有一个名字是 Symbol.iterator的属性
String Array Map Set 是内置可迭代的对象,因为它们的原型对象都有一个 @@iterator 方法
Object 不是
接收可迭代对象的API
数组的遍历 会调用迭代器接口,所以使用到数组作为参数的场合,都使用了遍历器
Map([iterable]) WeakMap([iterable])
Set([iterable]) WeakSet([iterable])
Promise.all([iterable]) Promise.race([iterable])
Array.from([iterable])
for...in for...of
getOwnPropertyNames
不能用 for...in 来迭代 Set, 因为 Set 中的元素没有 key, 使用 for...of 遍历
迭代器 与 迭代对象的差别:
迭代器是一种特殊的对象,每一个迭代器都有一个 next(),该方法返回一个对象,包括 value 和done 属性
// 实现一个返回迭代器对象的函数 function createIterator(items){ var i = 0; return { next () { var done = (i >= items.length); var value = !done ? items[i++] : "undefined" return { done, value } } } } const a = createIterator([1, 2, 3]); //该方法返回的最终是一个对象,包含value、done属性。 console.log(a.next()); //{value: 1, done: false} console.log(a.next()); //{value: 2, done: false} console.log(a.next()); //{value: 3, done: false} console.log(a.next()); //{value: undefined, done: true}
可迭代 和 可枚举的差别
举例说明不可迭代
let arrayLike = { 0: "aa", 1: "bb", 2: "cc", length: 3 } for (var item of arrayLike) { console.log(item) // TypeError: arrayLike is not iterable } let obj = { a: "monday", b: "sunday" } for (var item of obj) { console.log(item) // TypeError: obj is not iterable }
上面这个例子是想遍历一个 类数组对象 和 一个 对象, 因为它不可迭代,所以用 for...of不能遍历
报错TypeError: arrayLike is not iterable
但是使用 for...in 又可以遍历了
for (var item in arrayLike) { console.log(item) // 0 1 2 length } for (var item in obj) { console.log(item) // a b }
这是为什么呢?
附上阮一峰老师的解释
对象(Object)之所以没有默认部署Iterator接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。不过,严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作Map结构使用,ES5没有Map结构,而ES6原生提供了。
以及知乎上的解答为什么for...of对象不可迭代---贺师俊回调 , 写的很棒,一下就清晰了~
// 几种迭代方式 for (const k of Object.keys(obj)) ... // enumerable own keys for (const [k, v] of Object.entries(obj)) ... // enumerable own [key, value]s for (const k of Object.getOwnPropertyNames(obj)) // all own keys for (const s of Object.getOwnPropertySymbols(obj)) // all own symbols for (const k of Reflect.ownKeys(obj)) // all own keys (include symbols)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/99322.html
摘要:为什么不更规范点,令生成的是迭代器呢关于这个问题,我没找到官方解释,以下纯属个人观点。类型是什么以上是我对为什么不产生迭代器的一种解答。小结回顾全文,我得到了两个偏冷门的结论是可迭代对象而不是迭代器对象是不可变的等差序列。 showImg(https://segmentfault.com/img/bVbmKjd?w=6000&h=4000); 迭代器是 23 种设计模式中最常用的一种(...
摘要:示例代码如下此示例中可以看出,当迭代器终止时,通过抛出异常告知迭代器已耗尽。但如果迭代器所指向的数据结构在其存在时发生了插入或删除操作,则迭代器将可能失效。与的情形类似,对进行任何插入操作也将损坏迭代器。 花下猫语:之前说过,我对于编程语言跟其它学科的融合非常感兴趣,但我还说漏了一点,就是我对于 Python 跟其它编程语言的对比学习,也很感兴趣。所以,我一直希望能聚集一些有其它语言基...
摘要:简评迭代器是惰性可迭代对象,函数在中是一个惰性的可迭代对象,那么是不是迭代器呢为什么。如果你不能将某些东西传递给函数,那么它不是一个迭代器。的对象不是迭代器。 简评:迭代器(iterator)是惰性可迭代对象(lazy iterable),range 函数在 Python 3 中是一个惰性的可迭代对象,那么 range 是不是迭代器呢?为什么。 TLNR:Python 3 中的 ran...
阅读 2516·2023-04-26 02:47
阅读 3002·2023-04-26 00:42
阅读 868·2021-10-12 10:12
阅读 1375·2021-09-29 09:35
阅读 1692·2021-09-26 09:55
阅读 481·2019-08-30 14:00
阅读 1534·2019-08-29 12:57
阅读 2352·2019-08-28 18:00