源码共读第一天,【剔除对象中的属性】

200 阅读2分钟

2022.8.15 第一天源码共读,搞得正式一点🧐。

本次源码:[ 剔除对象中的属性 ]

核心代码:

    function omit(obj, fields) {
      // eslint-disable-next-line prefer-object-spread
      const shallowCopy = Object.assign({}, obj);
      for (let i = 0; i < fields.length; i += 1) {
        const key = fields[i];
        delete shallowCopy[key];
      }
      return shallowCopy;
    }

// export default omit;

疑惑:为什么这边要用到浅拷贝(Object.assign)?

我的理解是:如果说他需要返回一个新对象的话,为什么不深拷贝,可以传入一个配置项,让用户选择返回原对象还是返回新对象,我觉得这样是不是考虑周全一些,这个浅拷贝操作我属实有点不太明白,希望大佬们能指点指点。

在和群友讨论的时候想起来好久没写深拷贝了,就又写了一遍,亲测可用:

// 深拷贝
function deepClone(origin) {
  if (Object.prototype.toString.call(origin) === '[object Object]') {
    // 传入对象
    let cloneObject = {};
    // 遍历对象
    for (const key in origin) {
      if (origin.hasOwnProperty(key)) {
        // 检测到仍为引用对象,继续拷贝
        if (Object.prototype.toString.call(origin[key]) === '[object Object]' || Array.isArray(origin[key])) {
          // 递归深拷贝
          cloneObject[key] = deepClone(origin[key]);
        } else {
          // 检测到非引用对象,直接复制
          cloneObject[key] = origin[key];
        }
      }
    }
    return cloneObject;
  } else if (Array.isArray(origin)) {
    // 传入数组
    let cloneArray = [];
    // 遍历数组
    for (let index = 0; index < origin.length; index++) {
      // 检测到仍为引用对象,继续拷贝
      if (Object.prototype.toString.call(origin[index]) === 'object Object' || Array.isArray(origin[index])) {
        // 递归深拷贝
        cloneArray.push(deepClone(origin[index]));
      } else {
        // 检测到非引用对象,直接复制
        cloneArray.push(origin[index]);
      }
    }
    return cloneArray;
  } else {
    return origin;
  }
}

// 以下是测试代码
let testObject = {
  a: 1,
  b: 2,
  c: [
    1,
    2,
    3,
    {
      aaa: 'abc',
      bbb: [1, 4, 5, 55],
    },
  ],
  d: {
    aa: 'abc',
    bb: [1, 4, 5, 55],
  },
};

let copyObject = deepClone(testObject);

testObject.d.aa = 'def';
testObject.d.bb.pop();
testObject.c[0] = 0;
testObject.c[3].aaa = 'def';
testObject.c[3].bbb.pop();
console.log(testObject);
// 输出
/**
 * {
 *    a: 1,
 *    b: 2,
 *    c: [ 0, 2, 3, { aaa: 'def', bbb: [Array] } ], node终端打印不出来bbb的这个数组,可能层级太深了???
 *    d: { aa: 'def', bb: [ 1, 4, 5 ] }
 *  }
 */
console.log(copyObject);
// 输出
/**
 * {
 *   a: 1,
 *   b: 2,
 *   c: [ 1, 2, 3, { aaa: 'def', bbb: [Array] } ],
 *   d: { aa: 'abc', bb: [ 1, 4, 5, 55 ] }
 * }
 */

当我写到这里的时候,我的疑惑仍然存在,待后续评论解决吧。本次文章到此结束~~