• 作者:老汪软件技巧
  • 发表时间:2024-09-13 10:02
  • 浏览量:

不论是在面试还是在日常工作中或多或少都会用到深克隆相关的需求。

JSON.stringify()

缺点:如果对象中包含了函数、undefined、循环引用等特殊类型的数据,那么在转换时会忽略这些数据。

如:函数不会返回,其他的一些特殊类型;返回的都是null

let obj = {
  a: 1, 
  b: function () { }, 
  c: undefined, 
  d: true,
  e: Infinity,
  f: NaN,
  j: null
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj); // {a: 1, d: true, e: null, f: null, j: null}

简单深克隆

这个深克隆只是一个简单的克隆方法,面试的时候提出的这个问题。

因为该a对象是一个很简单的对象,但是如果直接复制的话会然后修改值,a也会被修改,所以需要将其保存到新的对象中即可。

let a = {
  c: '122',
  b: true
};
function deep (item) {
  if (!item || typeof item !== "object") {
    return item;
  }
  let list = Array.isArray(item) ? [] : {};
  for (const i in item) {
    list[i] = item[i];
  }
  return list;
}
let d = deep(a);
a.b = '999'
console.log(d.b); // true
console.log(a.b); // 999

递归深克隆

这个是一个简单递归深克隆

function deep (item) {
  // 判断是否是时间,如果是时间就直接将数据返回。
  if (Object.prototype.toString.call(item) === '[object Date]') return item;
  // 如果为空或者不为object时直接返回
  if (!item || typeof item !== "object") {
    return item;
  }
  // 如果是数组,list赋值空数组,否则空对象
  let list = Array.isArray(item) ? [] : {};
  // 循环遍历
  for (const i in item) {
    // 如果遍历数组为object类型,递归赋值
    if (typeof item[i] === 'object') {
      list[i] = deep(item[i]);
    } else {
      if (item.hasOwnProperty(i)) {
        list[i] = item[i];
      }
    }
  }
  return list;
}
let a = {
  c: '122',
  b: true,
  f: [
    {
      o:'我是o',
      list: [
        {
          p: '我是p'
        }
      ]
    }
  ]
};
let d = deep(a);
a.f[0].list[0].p = 'pppppppppppppppppppp'
console.log(a.f[0].list[0].p); // pppppppppppppppppppp
console.log(d.f[0].list[0].p); // 我是p

总结

其实在面试的时候觉得深拷贝好难,但是自己根据思考一步一步去写代码,有时候一下就感觉通透了。所以还是得多看多练。