什么是深拷贝?什么是浅拷贝?如何实现深拷贝?
深拷贝和浅拷贝是针对引用类型的
浅拷贝:
简单来说就是一个对象B复制另一个对象A,当改变B对象的值是A对象的值也随之改变。
举个例子
var obj1={a:1,b:5,c:3}; var obj2=obj1; obj2.b=2; console.log(obj1.b); //2 console.log(obj2.b); //2
可以看到两个对象的值都被修改了。
浅拷贝:就是拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,,任何一个修改都会是使得所有对象的值被修改,因为它们公用一条数据。
深拷贝:
简单来说就是一个对象B复制另一个对象A,当改变B对象的值是A对象的值不会改变。
举个例子:
var a=2; var b=a; b=3; console.log(a);//2 console.log(b);//3
以上例子说明两个变量使用的是独立的数据。对于基本数据类型来说不存在深拷贝、浅拷贝。直接赋值就是深拷贝。
深拷贝:深拷贝不会拷贝引用类型的引用,拷贝的是引用类型的值,形成一个新的引用类型。
如何实现深拷贝:
①JSON.Stringify(JSON.pare()) 不支持多层引用嵌套,不支持函数Map、Sep等类型的数据
var obj1={a:1,b:5,c:3}; var obj2=JSON.Stringify(JSON.parse(obj1)); obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
②展开运算符 ...
var obj1={a:1,b:5,c:3}; var obj2=(...obj1) obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
③Object.asssign(target,sourse)
var obj1={a:1,b:5,c:3}; var obj2=Object.assign({},obj1) obj2.b=2; console.log(obj1.b); //5 console.log(obj2.b); //2
④深拷贝函数,递归
// target 要拷贝的对象 function deepClone(target){ //定义一个拷贝对象 let result; // 判断拷贝目标是不是Object对象 if(typeof target==='object'){ // 判断是否是数组类型 if(Array.isArray(target)){ // 定义为数组 result=[]; for(let i in target){ result.push(deepClone(target[i])); } }else if(target===null){ // 直接赋值 result=null; }else if(target.constructor===RegExp){ // 直接赋值 result=target; // 不是特殊的对象 }else{ result={}; for(let i in target){ // 递归 result[i]=deepClone(target[i]); } } // 基本数据类型 直接赋值 }else{ result=target; } return result; }
var obj1={
a:{z:1,c:null},
b:[1,2,3,5],
c:function(){console.log(this.a)}
}
var obj2=deepClone(obj1);
console.log(obj2);
obj2.b[0]=2;
obj2.a[0]=2;
console.log(obj1.a)
console.log(obj2.a)
console.log(obj1.b)
console.log(obj2.b)
console.log(obj2.c())