封装一个迭代对象的方法

85 阅读1分钟

分析

对于迭代对象我们能想到的传统方法就是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
})