分析
对于迭代对象我们能想到的传统方法就是for in循环,但是此方法会存在一定弊端:
- 既可以迭代私有属性,又可以迭代公有属性(原型上的属性),尽管没有可枚举属性也会跑一遍,性能较差。
- 只能迭代可枚举、非Symbol类型的属性。
那怎么获取对象上所有的私有属性呢?(可枚举、不可枚举、不论类型)
Object.getOwnPropertyNames(arr)->获取对象非Symbol类型的私有属性(无关是否可枚举)
Object.getOwnPropertySymbol(arr)->获取Symbol类型的私有属性
两者一结合
let arr = [3, 2, Symbol(66)]
let keys =Object.getOwnPropertyNames(arr).concat(Object.getOwnPropertySymbols(arr))
keys.forEach(key => {
console.log(key,arr[key]); //3 2 Symbol(66) length(数组的不可枚举私有属性)
})
Es6中可直接使用Reflect.ownKeys(arr),但是弊端就是不兼容IE。
封装一个迭代对象的方法:
const each = (obj,callback) => {
if (obj === null || typeof obj !== "object") throw new TypeError('obj is not a object')
if (typeof callback !== "function") throw new TypeError('callback is not a function')
let keys = Reflect.ownKeys(obj)
keys.forEach(key => {
callback(key,obj[key])
})
}
each(arr, (key, value) => {
console.log(key,value); //3 2 Symbol(66) length
})