一:浅拷贝
let obj1 = {
a: 1
}
let obj2 = obj1;
obj2.a = 2;
console.log("obj1", obj1);
console.log("obj2", obj2);
我们可以看到obj1和obj2的属性a的值都变为2了,改变obj2的值,源对象obj1的值也跟着变,像这种情况成为浅拷贝。
二:深拷贝
let obj1 = {
a: 1
}
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.a = 2;
console.log("obj1", obj1);
console.log("obj2", obj2);
使用JSON.stringify和JSON.parse方法后,改变obj2的值,源对象obj1的值没有改变,这种称为深拷贝。
下面是实现深拷贝的方法,这些方法有使用区别
1:Object.assign()
2:JSON.stringify和JSON.parse
3:递归的方式实现对象的深拷贝
①Object.assign()
let obj1 = {
CnName: "姓名1",
childZi: {
EnName: "name1"
}
}
let obj2 = Object.assign({}, obj1);
obj2.CnName = "姓名2";
obj2.childZi.EnName = "name2";
console.log("obj1", obj1);
console.log("obj2", obj2);
我们可以看到改变拷贝对象obj2非嵌套的值,源对象obj1的值CnName不会跟着变;改变拷贝对象obj2内嵌套的对象值(obj2.childZi.EnName)后,原始对象嵌套的值也会跟着改变;Object.assign() 只能实现部分深拷贝。
②JSON.stringify和JSON.parse
let obj1 = {
CnName: "姓名1",
childZi: {
EnName: "name1"
},
childFunc: function(){
return this.CnName
}
}
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.CnName = "姓名2";
obj2.childZi.EnName = "name2";
console.log("obj1", obj1);
console.log("obj2", obj2);
JSON.stringify和JSON.parse会丢失源对象里面的函数childFunc;优点是子对象也实现了深拷贝,childZi里面的EnName没有随着obj2而改变。
③递归的方式实现对象的深拷贝
function myDeepClone(obj){
let clone;
if(obj == null || typeof obj != 'object') return obj;
clone = Object.assign({}, obj)
Object.keys(clone).forEach(key => {
clone[key] = typeof obj[key] === 'object'?myDeepClone(obj[key]):obj[key]
})
if(Array.isArray(obj)){
clone.length = obj.length
clone = Array.from(clone)
}
return clone
}
以上的自定义递归方法不够全面,但对于基本的对象( {} )和数组( [] )深拷贝还是够用的,要想实现复杂对象的深拷贝可以使用 lodash 的 cloneDeep 方法,这个方法实现深拷贝是比较完美的。
// 安装 lodash :npm i lodash
// main.js引入
import lodash from "lodash";
Vue.prototype.$cloneDeep = lodash.cloneDeep;
洽西游戏网