简单封装一个可以遍历对象,数组的函数

66 阅读1分钟
  • 基于传统的for/in循环,会存在一些弊端「性能较差(因为既可以迭代私有的属性,也能迭代公有的属性);只能迭代“可枚举、非Symbol类型”的属性...」

  • 解决思路:获取对象所有的私有属性「私有的、不论是否可枚举、不论类型」

    Object.getOwnPropertyNames(arr) -> 获取对象非Symbol类型的私有属性「无关是否可枚举」

    Object.getOwnPropertySymbols(arr) -> 获取对象Symbol类型的私有属性「无关是否可枚举」

    两个集合并在一起,即为所有的私有属性,Object.getOwnPropertyNames(arr).concat(Object.getOwnPropertySymbols(arr))

    不考虑兼容情况下:Reflect.ownKeys(arr) 。不兼容IE。

/**
 * 迭代对象的方法(无关该属性是否是Symbol或者可枚举)
 * @param {*} object 需要遍历的对象
 * @param {*} callback 遍历每次执行的回调函数 (val, key)=>{}
 */
function _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!");
  // Reflect.ownKeys(obj);
  const _ownKeys = Object.getOwnPropertySymbols(obj).concat(Object.getOwnPropertyNames(obj));
  _ownKeys.forEach(key => callback(obj[key], key));
}
let a = [1, 9],
  b = { a: '你', b: '好', c: '世', d: '界' };
_each(a, (val, key) => {
  console.log(111, val, key);
});
_each(b, (val, key) => {
  console.log(222, val, key);
});
// _each(b, 1); // TypeError: callback is not a function!
// _each(5, () => {}); // TypeError: obj is not a object!

image.png