深拷貝和淺拷貝是針對(duì)引用類(lèi)型的
淺拷貝:
簡(jiǎn)單來(lái)說(shuō)就是一個(gè)對(duì)象B復(fù)制另一個(gè)對(duì)象A,當(dāng)改變B對(duì)象的值是A對(duì)象的值也隨之改變。
舉個(gè)例子:
var obj1={a:1,b:5,c:3};
var obj2=obj1;
obj2.b=2;
console.log(obj1.b); //2
console.log(obj2.b); //2
可以看到兩個(gè)對(duì)象的值都被修改了
淺拷貝:只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身敷存,相當(dāng)于是新建了一個(gè)對(duì)象,該對(duì)象復(fù)制了原對(duì)象的指針,新舊對(duì)象還是共用一個(gè)內(nèi)存塊瘪贱,任何一個(gè)修改都會(huì)是使得所有對(duì)象的值被修改
應(yīng)用場(chǎng)景:從服務(wù)器fetch到數(shù)據(jù)之后我將其存放在store中,通過(guò)props傳遞給界面辆毡,然后我需要對(duì)這堆數(shù)據(jù)進(jìn)行修改菜秦,那涉及到的修改就一定有保存和取消,所以我們需要將這堆數(shù)據(jù)拷貝到其它地方
深拷貝:
簡(jiǎn)單來(lái)說(shuō)就是一個(gè)對(duì)象B復(fù)制另一個(gè)對(duì)象A舶掖,當(dāng)改變B對(duì)象的值是A對(duì)象的值不會(huì)改變球昨。
舉個(gè)例子:
var a=2;
var b=a;
b=3;
console.log(a);//2
console.log(b);//3
以上例子說(shuō)明兩個(gè)變量使用的是獨(dú)立的數(shù)據(jù)。對(duì)于基本數(shù)據(jù)類(lèi)型來(lái)說(shuō)不存在深拷貝眨攘、淺拷貝主慰。直接賦值就是深拷貝。
深拷貝:深拷貝不會(huì)拷貝引用類(lèi)型的引用期犬,拷貝的是引用類(lèi)型的值河哑,形成一個(gè)新的引用類(lèi)型。新建一個(gè)一模一樣的對(duì)象龟虎,該對(duì)象與原對(duì)象不共享內(nèi)存璃谨,修改新對(duì)象也不會(huì)影響原對(duì)象
應(yīng)用場(chǎng)景:當(dāng)你想使用某個(gè)對(duì)象的值,在修改時(shí)不想修改原對(duì)象鲤妥,那么可以用深拷貝弄一個(gè)新的內(nèi)存對(duì)象佳吞。像es6的新增方法都是深拷貝,所以推薦使用es6語(yǔ)法
如何實(shí)現(xiàn)深拷貝:
①JSON.Stringify(JSON.pare()) 不支持多層引用嵌套棉安,不支持函數(shù)Map底扳、Sep等類(lèi)型的數(shù)據(jù)
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
②jQuery.extend()方法,第一個(gè)參數(shù)要傳true
③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
④深拷貝函數(shù),遞歸
// target 要拷貝的對(duì)象
function deepClone(target){
//定義一個(gè)拷貝對(duì)象
let result;
// 判斷拷貝目標(biāo)是不是Object對(duì)象
if(typeof target==='object'){
// 判斷是否是數(shù)組類(lèi)型
if(Array.isArray(target)){
// 定義為數(shù)組
result=[];
for(let i in target){
result.push(deepClone(target[i]));
}
}else if(target===null){
// 直接賦值
result=null;
}else if(target.constructor===RegExp){
// 直接賦值
result=target;
// 不是特殊的對(duì)象
}else{
result={};
for(let i in target){
// 遞歸
result[i]=deepClone(target[i]);
}
}
// 基本數(shù)據(jù)類(lè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())