JS面试题之手撸深浅拷贝

118 阅读1分钟

屡见不鲜的题目了,今天尝试分别实现一个深拷贝和浅拷贝。

先上点开胃小菜的吧---浅拷贝:

浅拷贝的方法其实有很多,比如直接赋值给一个变量Object.assign({},obj)展开运算符{...obj}等,这边还是自己手写代码实现。

function shallowClone(obj){
  if (!obj || typeof obj !== 'object' || obj == null) {
    return obj;
  }
  let res;
  for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
        res[key] = obj[key];
    }
  }

  return res;
}

下面是深拷贝: 浅拷贝+递归。 了解:Object.getOwnPropertySymbols()WeakMap

function (obj, hash = new WeakMap()) {
  if (!obj || typeof obj !== 'object' || obj == null) {
    return obj;
  }

  if (hash.has(obj)) return hash.get(obj); // 读取缓存

  let res = Array.isArray(obj) ? [] : {};
  hash.set(obj, res); // 设置缓存
  
  // ------------------------ 对Symbol类型进行深拷贝
  let symbols = Object.getOwnPropertySymbols(obj);
  if (symbols.length) {
    symbols.forEach((sym) => {
      if (typeof obj[sym] === 'object' && obj[sym] !== null) {
        res[sym] = this.deepClone(obj[sym], hash);
      } else {
        res[sym] = obj[sym];
      }
    });
  }
  // ------------------
    
  for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) { 
      // 添加 数据类型判断
      if (typeof obj[key] === 'object' && obj[key] !== null) { 
      // 引用值
        res[key] = this.deepClone(obj[key], hash);
      } else { 
      // 原始值
        res[key] = obj[key];
      }
    }
  }
  return res;
};

可以对重复代码进行提取优化。 如有错误,欢迎评论指出。谢谢!