深拷贝浅拷贝区别
数据类型分为两种基础类型和引用类型:
1、基础类型:像Number、String、Boolean等这种为基本类型
2、引用类型:Object和Array
1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 ; 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,另一处修改,你当下的对象也会修改。例(Object.assign())或者展开运算符
var Chinese = {
nation: "中国"
};
var Doctor = {
career: "医生"
};
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.buer = p;
return c;
}
Doctor = extendCopy(Chinese);
Doctor.career = "܅医生";
alert(Doctor.nation); // 中国
但是,这样的拷贝有一个问题,那就是,如果父对象的属性等于数组或者另一个对象,那么实际上子对象获得的只是一个内存地址,而不是真正的拷贝,因此存在父对象被篡改的可能
现在给Chinese添加一个’’出生地’’ 属性,它的值是一个数组
Chinese.birthPlaces = ["北京", "上海", "杭州"];
//通过extendCopy()函数,Doctor继承了Chinese̶
Doctor = extendCopy(Chinese);
//然后,我们为Doctor的"出生地"添加一个城市
Doctor.birthPlaces.push("重庆");
//看一下输入结果
alert(Doctor.birthPlaces); //北京,上海,杭州,重庆
alert(Chinese.birthPlaces); //北京,上海,杭州,重庆
//结果是两个的出生地都被改变了
所以,extendCopy()只是拷贝了基本类型的数据,我们把这种拷贝称为"浅拷贝"
2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”;引用对象的值等信息,复制一份一样的,就是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝
可以通过 JSON.parse(JSON.stringify(object))
来解决,但是此方法无法复制函数类型
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
该方法也是有局限性的
1、会忽略 undefined
2、不能序列化函数
3、不能解决循环引用的对象