JS 浅拷贝和深拷贝

140 阅读1分钟

对JS对象进行复制的时候,有两种拷贝方式,一种是浅拷贝,一种是深拷贝。

一 浅拷贝

浅拷贝只复制对象的第一层属性,如果属性是基本类型,则直接复制值;如果属性是引用类型,则复制其内存地址(引用)。因此,如果原始对象的基本类型属性被修改,拷贝对象的属性不会被修改;如果原始对象的引用类型属性被修改,由于拷贝对象和原始对象指向同一内存地址,拷贝对象中的相应属性也会被修改。

实现浅拷贝的方法:

  1. 展开运算符:{ ...obj }
  2. Object.assign():Object.assign({}, obj)
  3. 数组的slice方法(用于数组):arr.slice()
  4. Array.from()(用于数组):Array.from(arr)

二 深拷贝

深拷贝会复制对象的所有层级,无论对象包含基本类型还是引用类型,每一层都是新创建的值,而不是引用原始对象中的值,因此会创建一个完全独立的副本,使得原始对象和拷贝对象之间不存在任何共享的引用。

实现深拷贝的方法:

  1. JSON.parse(JSON.stringify(object))
  2. 使用递归进行深拷贝
function deepClone(target) {
   if (target === null || typeof target !== 'object') {
     return target;
   }
   // let cloneTarget = target.constructor === Array ? [] : {};
   let cloneTarget = Array.isArray(target) ? [] : {};
   Object.keys(target).forEach(key => {
     if (target[key] && typeof target[key] === 'object') {
       cloneTarget[key] = deepClone(target[key]);
     } else {
       cloneTarget[key] = target[key];
     }
   });
   return cloneTarget;
 }
  1. 使用第三方库:比如 Lodash 的 _.cloneDeep 方法

总结

深拷贝会让新对象和原始对象完全解耦,而浅拷贝的方式创建的新对象和原始对象之间还有联系。