for in
for in
用来遍历对象的可枚举、非 Symbol 的所有属性。
这句话里有这么几个需要注意的地方:
- 😸 遍历的一般是对象,数组也不是不行,毕竟数组也是一种对象,但是可能没那么直观
- 😸 遍历的是对象的属性,而不是值
- 😸 属性的 key 必须是 enumerable & not Symbol 的
- 😸 除了自有属性,也会遍历继承属性(原型链)
😅 遍历数组
虽然 for in
一般不用来遍历数组,但是我们还是可以看看遍历结果长啥样:
const x = [1,2,3]
for (const a in x) console.log(typeof(a),a)
可以看到结果是:
string 0
string 1
string 2
指的注意的有两个:
- 😸 遍历的值是索引,因为数组作为一种特殊的对象,其索引可以看做属性
- 😸 索引作为 key 时的类型是
string
而不是number
,但是我们仍然可以x['1']
,因为它本身就是合法的,等价于x[1]
我们给数组添加一个属性:
x.name = 'age'
// 在计算 length 是并不会考虑这种属性
console.log(x.length) //=> 3
for (const a in x) console.log(typeof(a),a)
此时打印结果是:
string 0
string 1
string 2
string name
length
也是数组的一个属性,但它是不可枚举的:
console.log(x.__proto__.propertyIsEnumerable('length')) //=> false
正常情况下,数组中除了索引属性外,其它属性都是不可枚举的。
for of
另一个容易混淆的是 for of
,它是 ES6 引入的、能够适应多种数据结构的遍历方式。
for of
能遍历的对象的前提是该对象是 可迭代的,这意味该对象上有一个 [Symbol.iterator]
属性,它是一个函数,这个函数没有参数,并且返回一个迭代器。for of
遍历对象实际上就是循环调用这个迭代器的 next()
方法。
默认情况下(未修改数组的迭代器),数组的迭代器会按顺序从前往后依次返回值,所以我们一般用 for of
来遍历数组。
实际上,任何可迭代的对象(例如内置的 Array
, TypedArray
, Set
, Map
)都可以使用 for of
来迭代。
Reference
👉 可迭代与迭代器
评论区