浅拷贝:只拷贝对象的基础属性值,对属性值为对象或数组的属性则拷贝指针。
深拷贝:拷贝对象的所有属性作为一个全新的对象。拷贝前后的对象互不影响。
浅拷贝仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅拷贝出来的对象也会相应改变。
一、对象引用
对象引用容易理解,直接赋值,修改复制后的数组,原对象会随之改变。
//对象引用
var boy = {
age:18
}
var girl = boy;
console.log(boy === girl);//true
girl.age = 20;
console.log(boy.age);//20
理解:使用“=”进行赋值,girl和boy指向了同一内容地址,修改一个,另一个也会修改。
二、浅拷贝
使用Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
//浅拷贝
var boy = {
age:18
}
var girl = Object.assign({}, boy);
console.log(boy === girl);//false
girl.age = 20;
console.log(boy.age);//18
理解:上述代码将原始对象拷贝到一个空对象,就得到原始对象的克隆,原对象和拷贝对象指向不同的内存地址,修改原对象和克隆对象,互不影响。
var boy = {
age:18,
address:{
home:'北京'
}
}
var girl = Object.assign({}, boy);
console.log(boy === girl);//false
girl.address.home = '上海';
console.log(boy.address.home);//上海
理解:上述代码将原始对象拷贝到一个空对象,就得到原始对象的克隆。因为Object.assign()只是浅拷贝girl.address是对栈对象的引用,因此内层对象的修改会影响原始对象。
三、深拷贝
1、JSON.parse()与JSON.stringify()深拷贝
可以通过JSON对象的方法,来进行对象的深拷贝,代码如下:
//纯数据json对象的深度克隆
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
理解:通过对象符串化和字符串对象化进行对象的拷贝。此方法只使用与纯JSON对象的深拷贝
2 利用递归方式实现深拷贝
function deepClone(obj){
let dobj = Array.isArray(obj)?[]:{};
if(obj && typeof obj === "object"){
for (var key in obj){
if(obj.hasOwnProperty(key)){
//当属性是引用类型的object时 则递归深拷贝
if(obj[key] && typeof obj[key] === "object"){
dst[key]=deepClone(obj[key])
}else{
dst[key]=obj[key]
}
}
}
}
return dobj;
}
再使用的话如下
var obj1 = {
name:'zhangsan',
age:20,
sex:{
max:"nan"
}
}
var obj2 = deepClone(obj1)
obj1.sex.max = "nv";
console.log(obj1)
console.log(obj2)
打印结果如下: