js 深浅拷贝

2021-03-10  本文已影响0人  McDu

深拷贝

function deepCopy (obj) {
    if(!obj || typeof obj !== 'object') {
        return;
    }
    
    let res = Array.isArray(obj) ? [] : {};
    
    for(const key in obj) {
        if(obj.hasOwnProperty(key)) {
            const val = obj[key];
            res[key] = typeof val === 'object' ? deepCopy(val) : val;
        }
    }

    return res;
}

更好的写法:

function deepCopy(obj) {

  function isObject(o) {
      return (typeof o === 'object' || typeof o === 'function') && o !== null
  }
  
  if(!isObject(obj)) {
    return;
  }

  let newObj = Array.isArray(obj) ? [] : {};

  Reflect.ownKeys(obj).forEach(key => {
      const val = obj[key];
      newObj[key] = isObject(val) ? deepCopy(val) : val
  });
  
  return newObj;
}

深拷贝循环引用

1、通过闭包维护一个变量,变量中储存已经遍历过的对象
2、每次递归时判断当前的参数是否已经存在于变量中,如果已经存在,就说明已经递归过该变量,就可以停止这次递归并返回上次递归该变量时的返回值

function deepCopy(obj) {
  let visitedObjs = [];

  function baseClone(target) {
      if(!obj || typeof obj !== 'object') {
        return target;
    }
    
    for(let i = 0; i < visitedObjs.length; i++) {
      if(visitedObjs[i].target === target ) {
        return visitedObjs[i].result;
      }
    }

    let result = Array.isArray(target) ? [] : {};
    
     visitedObjs.push({target , result})
      Reflect.ownKeys(obj).forEach(key => {
      const val = obj[key];
      result[key] = isObject(val) ? baseClone(val) : val
    });
    return result;
  }
  return baseClone(obj);
}

浅拷贝

function deepCopy (obj) {
    if(!obj || typeof obj !== 'object') {
        return;
    }
    
    let res = Array.isArray(obj) ? [] : {};
    
    for(const key in obj) {
        if(obj.hasOwnProperty(key)) {
            const val = obj[key];
            res[key] = val;
        }
    }

    return res;
}

浅拷贝,还可以用 Object.assign 、展开运算符 ...

上一篇 下一篇

猜你喜欢

热点阅读