浅拷贝与深拷贝

208 阅读2分钟

对象的深拷贝与浅拷贝

数组,json对象等操作常会碰到这种情况,复制一个对象后,改变改对象,复制过来的对象也被改变,这其实是浅拷贝,拷贝分为深拷贝和浅拷贝,拷贝其实是地址的引用问题

浅拷贝

浅拷贝会拷贝基本的数据类型,String,Number,Boolean,Null,undefined,对于引用数据类型,还是会发生引用,es6的...只是一层的浅拷贝

引用类型

数组

let arr = [1, 2, 3, 4];
let arrCopy = [];
arrCopy = [...arr];
arrCopy.push(5);
arr.push(6);
console.log(arr);
console.log(arrCopy);
result:
[ 1, 2, 3, 4, 6 ]
[ 1, 2, 3, 4, 5 ]

json数组

let arr = [{
  name: "张三",
  age: 24
},
{
  name: "李四",
  age: 22
}]

let arrCopy = [...arr];
console.log(arrCopy);
arr[0].name = "王五";
console.log(arrCopy);
result:
[ { name: '张三', age: 24 }, { name: '李四', age: 22 } ]
[ { name: '王五', age: 24 }, { name: '李四', age: 22 } ]

json:

let json = {
  name: "李四",
  age: 22,
  address: {
    province: "河南",
    city: "焦作"
  }
}

let jsonCopy = { ...json };
console.log(jsonCopy);
json.name = "张三";
json.address.province = "江苏"
console.log(jsonCopy);
result:
{ name: '李四', age: 22, address: { province: '河南', city: '焦作' } }
{ name: '李四', age: 22, address: { province: '江苏', city: '焦作' } }

深拷贝

完全开辟一个新的地址存复制过来的数据,两者互不干涉

JSON.parse(JSON.stringify(arr))对数组和json深拷贝没问题,但是函数,正则等的话不会深拷贝.例如第二个例子,function未拷贝进去

let arr = [{
 name: "张三",
 age: 24
},
{
 name: "李四",
 age: 22
}]

let arrCopy = JSON.parse(JSON.stringify(arr));
console.log(arrCopy)
result:
[
 { name: '张三', age: 24},
 { name: '李四', age: 22 }
]
let arr = [{
 name: "张三",
 age: 24,
 address: {
   province: "河南",
   city: "焦作"
 },
 getAge: function () {
   return this.age
 }
},
{
 name: "李四",
 age: 22
}]

let arrCopy = JSON.parse(JSON.stringify(arr));
arr[0].address.province = "江苏";
console.log(arr);
console.log(arrCopy);
result:
[
 {
   name: '张三',
   age: 24,
   address: { province: '江苏', city: '焦作' },
   getAge: [Function: getAge]
 },
 { name: '李四', age: 22 }
]
[
 { name: '张三', age: 24, address: { province: '河南', city: '焦作' } },
 { name: '李四', age: 22 }
]

递归实现深拷贝,这个可以当做一个公共函数使用

function deepCopy(obj) {
 let result = obj;
 if (typeof obj === 'object' && obj !== null) {
   result = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
   for (let prop in obj) {
     result[prop] = deepCopy(obj[prop]);
   }
 }
 return result;
}
let arrCopy = deepCopy(arr)
console.log(arrCopy)
result:
[
 {
   name: '张三',
   age: 24,
   address: { province: '河南', city: '焦作' },
   getAge: [Function: getAge]
 },
 { name: '李四', age: 22 }
]

参考:
segmentfault.com/a/119000001…
www.jianshu.com/p/dd2928490…