对象的深拷贝与浅拷贝
数组,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…