常常看到迭代
这个词,那末归总下吧~
什么是
可迭代对象:
一个对象(或它的原型链上的某个对象)必须有一个名字是 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)