日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

原來(lái)深拷貝與淺拷貝是這樣?

 


原來(lái)深拷貝與淺拷貝是這樣?

 

為了讓讀者更好的理解深淺拷貝,在講深淺拷貝之前要引入基本數(shù)據(jù)類型 , 引用數(shù)據(jù)類型 和 數(shù)據(jù)儲(chǔ)存(棧和堆)這幾個(gè)概念,如果已經(jīng)理解,可直接跳過(guò)這一part。

JS數(shù)據(jù)類型

Q:前端面試常問(wèn),JS的基本數(shù)據(jù)類型有哪些呀?

A:JS數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,詳細(xì)分類如下:

原來(lái)深拷貝與淺拷貝是這樣?

 

Q:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的儲(chǔ)存方式有什么不同?

A:

  • 基本數(shù)據(jù)類型:變量名和值都儲(chǔ)存在棧內(nèi)存中,例如:
var num=10;

num變量在內(nèi)存中儲(chǔ)存如下:

原來(lái)深拷貝與淺拷貝是這樣?

 

  • 引用數(shù)據(jù)類型:變量名儲(chǔ)存在棧內(nèi)存中,值儲(chǔ)存在堆內(nèi)存中,但是堆內(nèi)存中會(huì)提供一個(gè)引用地址指向堆內(nèi)存中的值,而這個(gè)地址是儲(chǔ)存在棧內(nèi)存中的,例如:
var arr=[1,2,3,4,5];

arr變量在內(nèi)存中的儲(chǔ)存如下:

原來(lái)深拷貝與淺拷貝是這樣?

 

對(duì)這幾個(gè)概念有了初步了解之后,接下來(lái)正式開(kāi)始講深淺拷貝。

什么是淺拷貝和深拷貝

在講兩者概念之前我們先看一個(gè)需求:現(xiàn)在有一個(gè)對(duì)象A,需求是將A拷貝一份到B對(duì)象當(dāng)中?

淺拷貝

當(dāng)B拷貝了A的數(shù)據(jù),且當(dāng)B的改變會(huì)導(dǎo)致A的改變時(shí),此時(shí)叫B淺拷貝了A,例如:

//淺拷貝
var A={
 name:"martin",
 data:{num:10}
}
var B={}
var B=A;
B.name="lucy";
console.log(A.name); //lucy

A直接賦值給B后,B中name屬性的改變導(dǎo)致了A中name屬性也發(fā)生了變化。

其實(shí)是因?yàn)檫@種賦值方式只是將A的堆內(nèi)存地址賦值給了B,A和B儲(chǔ)存的是同一個(gè)地址,指向的是同一個(gè)內(nèi)容,因此B的改變當(dāng)然會(huì)引起A的改變。

淺拷貝的方式

直接賦值

第一種方式就是上面所寫代碼中的將對(duì)象地址直接進(jìn)行賦值。

var A={
 name:"martin",
 data:{num:10}
};
var B={};
B=A;
B.name="lucy";
console.log(A.name); //"lucy",A中name屬性已改變

Object.assign(target,source)

這是ES6中新增的對(duì)象方法,對(duì)它不了解的見(jiàn)ES6對(duì)象新增方法,它可以實(shí)現(xiàn)第一層的“深拷貝”,但無(wú)法實(shí)現(xiàn)多層的深拷貝。

以當(dāng)前A對(duì)象進(jìn)行說(shuō)明

第一層“深拷貝”:就是對(duì)于A對(duì)象下所有的屬性和方法都進(jìn)行了深拷貝,但是當(dāng)A對(duì)象下的屬性如data是對(duì)象時(shí),它拷貝的是地址,也就是淺拷貝,這種拷貝方式還是屬于淺拷貝。

多層深拷貝:能將A對(duì)象下所有的屬性,及時(shí)屬性是對(duì)象,也能夠深拷貝出來(lái),讓A和B相互獨(dú)立,這種叫才叫深拷貝。

var A={
 name:"martin",
 data:{num:10},
 say:function(){
 console.log("hello world") 
 }
}
var B={}
Object.assign(B,A); //將A拷貝到B
B.name="lucy";
console.log(A.name); //martin,發(fā)現(xiàn)A中name并沒(méi)有改變
B.data.num=5;
console.log(A.data.num); //5,發(fā)現(xiàn)A中data的num屬性改變了,說(shuō)明data對(duì)象沒(méi)有被深拷貝

淺拷貝總結(jié)

直接賦值:這種方式實(shí)現(xiàn)的就是純粹的淺拷貝,B的任何變化都會(huì)反映在A上。

Object.assign():這種方式實(shí)現(xiàn)的實(shí)現(xiàn)的是單層“深拷貝”,但不是意義上的深拷貝,對(duì)深層還是實(shí)行的淺拷貝。

深拷貝

當(dāng)B拷貝了A的數(shù)據(jù),且當(dāng)B的改變不會(huì)導(dǎo)致A的改變時(shí),此時(shí)叫B深拷貝了A,例如:

//深拷貝
var A={
 name:"martin",
 data:{num:10},
 say:function(){
 console.log("hello world") 
 }
} //開(kāi)辟了一個(gè)新的堆內(nèi)存地址,假設(shè)為placaA
var B={}; //又開(kāi)辟了一個(gè)新的堆內(nèi)存地址,假設(shè)為placeB
B=JSON.parse(JSON.stringfy(A));
B.name="lucy";
console.log(A.name); //martin

通過(guò)JSON對(duì)象方法實(shí)現(xiàn)對(duì)象的深拷貝,我們可以看到其中B.name值的改變并沒(méi)有影響A.name的值,因?yàn)锳和B分別指向不同的堆內(nèi)存地址,因此兩者互不影響。

深拷貝的方式

理解了深淺拷貝,接下來(lái)說(shuō)一下深拷貝的幾種方式。

首先假設(shè)一個(gè)已知的對(duì)象A,然后需要把A深拷貝到B。

var A={
 name:"martin",
 data:{num:10},
 say:function () {
 console.log("say");
 }
};
var B={};

遞歸賦值

function deepCopy(A,B) {
 for(item in A){
 if(typeof item=="object"){
 deepCopy(item,B[item]);
 }else{
 B[item]=A[item];
 }
 }
}
deepCopy(A,B);
B.data.num=5;
console.log(A.data.num); //10,A中屬性值并沒(méi)有改變,說(shuō)明是深拷貝

通過(guò)這種方式能實(shí)現(xiàn)深層拷貝,而且能自由控制拷貝是如何進(jìn)行的,如:當(dāng)B中有和A同名的屬性,要不要重新賦值?這些都可以進(jìn)行控制,但是代碼相對(duì)復(fù)雜一些。

JSON.parse()和JSON.stringify

var B=JSON.parse(JSON.stringify(A));
B.data.num=5;
console.log(A.data.num); //10,A中屬性值并沒(méi)有改變,說(shuō)明是深拷貝

用這種方式實(shí)現(xiàn)深拷貝的時(shí)候要 注意 , 函數(shù)是無(wú)法進(jìn)行拷貝的,會(huì)被丟失 ,上述代碼中B也并沒(méi)有拷貝出A中的say函數(shù),這和JSON.stringify方法的規(guī)則有關(guān)系,它在序列化的時(shí)候會(huì)直接忽略函數(shù),因此最后A中的say函數(shù)沒(méi)有被拷貝到B,關(guān)于JSON.stringify序列化的具體規(guī)則見(jiàn)JSON.stringify指南。

深拷貝總結(jié)

遞歸:使用遞歸進(jìn)行深拷貝時(shí)比較靈活,但是代碼較為復(fù)雜;

JSON對(duì)象:JSON對(duì)象方法實(shí)現(xiàn)深拷貝時(shí)比較簡(jiǎn)單,但是當(dāng)拷貝對(duì)象包含方法時(shí),方法會(huì)被丟失;

因此使用者可按自身的使用場(chǎng)景來(lái)選擇拷貝方式

分享到:
標(biāo)簽:拷貝
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定