for…in 和 for…of
for…in
以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性(MDN官方的解释)。多用于遍历对象,也可以遍历数组。
如何判断对象的属性是不是可枚举的,可以使用propertyIsEnumerable。定义对象属性的方法有多种,比如obj.xxx = yyy或者Object.defineProperty(),代码如下
let obj = {}
obj.aa = 123
obj[Symbol(123)] = 123
Object.defineProperty(obj, 'bb', {
value: 2,
enumerable: false // 默认就是false
})
obj.propertyIsEnumerable('aa') // true
obj.propertyIsEnumerable('bb') // false
for(const item in obj) {
console.log(item) // aa, bb Symbol(123) 不会输出
}
如果想获取对象上定义的所有属性,可以使用:
- Reflect.ownKeys():获取目标对象自身的属性键组成的数组
- Object.getOwnPropertyNames:不能获取symbol值作为名称的属性
- Object.getOwnPropertySymbols:获取给定对象所有自有 Symbol 属性的数组
- Reflect.ownKeys() = getOwnPropertyNames + getOwnPropertySymbols
Reflect.ownKeys(obj) // [aa, bb, Symbol(123)]
Object.getOwnPropertyNames(obj) // [aa, bb]
Object.getOwnPropertySymbols(obj) // [Symbol(123)]
for…of
用于遍历可迭代对象 (具体可参考MDN), 可以查看目标对象的原型对象是否有下图的属性来判断是否是可迭代对象 。
使用
// array
const targetData = [1, 3 ,5]
for (const item of targetData) {
console.log(item); // 1 3 5
}
// string
const str = 'woaixuexi'
for (const s of str) {
console.log(s); // w o ... x i
}
// map
const map = new Map()
map.set('m1', 123)
for (const m of map) {
console.log(s); // ['m1', 123]
}
for (let [key, value] of map) {
console.log(key, value); // 'm1' 123
}
// set arguments ... 等等可以自己尝试下