JS進(jìn)階篇-深拷貝與淺拷貝

?一蛔溃、淺拷貝

在定義一個(gè)對(duì)象或數(shù)組時(shí),變量存放的往往是一個(gè)引用地址瓦宜。當(dāng)我們使用對(duì)象拷貝時(shí)蔚万,如果屬性是對(duì)象或數(shù)組時(shí)這是我們傳遞的也只是一個(gè)地址。因此子對(duì)象在訪問(wèn)該屬性時(shí)临庇,會(huì)根據(jù)地址回溯到父對(duì)象指向的堆內(nèi)存中反璃,即父子對(duì)象發(fā)生了關(guān)聯(lián),兩者的屬性值會(huì)指向同一內(nèi)存空間假夺。

var a = {key1: '1'};

function copy(p) {

? ? var c = {};

? ? for(var i in p){

? ? ? ? c[i] = p[i]

????}

? ? return c;

}

a.key2 = ['1', '2', '3'];

var b = copy(a);

b.key3 = '3';

b.key2.push('4');

console.log(a);? ? // {key1: '1', key2: ['1', '2', '3', '4']}

console.log(b);? ? // {key1: '1', key2:?['1', '2', '3', '4'], key3: '3'}

但是若是修改的屬性變?yōu)閷?duì)象或數(shù)組時(shí)淮蜈,那么父子對(duì)象之間就發(fā)生關(guān)聯(lián),從上可知:

stack/heap

原因是key1的值屬于基本類型已卷,所以拷貝的時(shí)候傳遞的就是該數(shù)據(jù)段梧田;但是key2的值是堆內(nèi)存中的對(duì)象,所以key2在拷貝的時(shí)候傳遞的是指向key2對(duì)象的地址侧蘸,無(wú)論復(fù)制多少個(gè)key2裁眯,其值始終是指向父對(duì)象的key2對(duì)象的內(nèi)存空間。

實(shí)現(xiàn)淺拷貝的方法:

var a = {name: '123'};

var b = Object.assign({}, a);

b.age = 1;

console.log(a.age);? ? // undefined

var a = [1,2,3];

var b = a.slice();

b.push(4);

console.log(a);? ? // [1,2,3]

console.log(b);? ? // [1,2,3,4]

var a = [1,2,3];

var b = a.concat();

b.push(4);

console.log(a);? ? // [1,2,3]

console.log(b);? ? // [1,2,3,4]

var a = [1,2,3];

var b = [...a];

console.log(a);? ? // [1,2,3]

console.log(b);? ? // [1,2,3,4]

二闺魏、深拷貝

獲取以上并不是我們?cè)趯?shí)際編碼中想要的結(jié)果未状,我們不希望父子對(duì)象之間的關(guān)聯(lián),那么這時(shí)候就可以用到深拷貝析桥。既然屬性值類型是數(shù)組或?qū)ο髸r(shí)只會(huì)傳地址司草,那么我們就用遞歸來(lái)解決這個(gè)問(wèn)題。把父對(duì)象中所有屬于對(duì)象的屬性類型都遍歷賦給子對(duì)象即可泡仗。

var a = [key: '1'];

function copy(p, c){

? ? var c = c || {};

? ? for(var i in p){

? ? ? ? if(typeof p[i] === 'object') {

? ? ? ? ? ? c[i] = (p[i].constructor === Array)?[]:{}

? ? ? ? ? ? copy(p[i], c[i])

????????} else {

? ? ? ? ? ? c[i] = p[i]

????????}

????}

? ? return c;

}

a.key2 = [1,2,3];

var b = {};

b = copy(a, b);

b.key2.push(4);

console.log(a.key2);? ? // [1,2,3]

console.log(b.key2);? ? // [1,2,3,4]

stacj/heap

最后:?總結(jié)基本數(shù)據(jù)類型和引用數(shù)據(jù)類型區(qū)別

1埋虹、聲明變量時(shí)內(nèi)存分配不同

 *原始類型:在棧中,因?yàn)檎紦?jù)空間是固定的娩怎,可以將他們存在較小的內(nèi)存中-棧中搔课,這樣便于迅速查詢變量的值

 *引用類型:存在堆中,棧中存儲(chǔ)的變量截亦,只是用來(lái)查找堆中的引用地址爬泥。

 ? ?這是因?yàn)椋阂弥档拇笮?huì)改變,所以不能把它放在棧中崩瓤,否則會(huì)降低變量查尋的速度袍啡。相反,放在變量的椚赐埃空間中的值是該對(duì)象存儲(chǔ)在堆中的地址境输。地址的大小是固定的蔗牡,所以把它存儲(chǔ)在棧中對(duì)變量性能無(wú)任何負(fù)面影響

2、不同的內(nèi)存分配帶來(lái)不同的訪問(wèn)機(jī)制

在javascript中是不允許直接訪問(wèn)保存在堆內(nèi)存中的對(duì)象的嗅剖,所以在訪問(wèn)一個(gè)對(duì)象時(shí)辩越,首先得到的是這個(gè)對(duì)象在堆內(nèi)存中的地址,然后再按照這個(gè)地址去獲得這個(gè)對(duì)象中的值信粮,這就是傳說(shuō)中的按引用訪問(wèn)黔攒。

? ? 而原始類型的值則是可以直接訪問(wèn)到的。

3蒋院、復(fù)制變量時(shí)的不同

1)原始值:在將一個(gè)保存著原始值的變量復(fù)制給另一個(gè)變量時(shí)亏钩,會(huì)將原始值的副本賦值給新變量莲绰,此后這兩個(gè)變量是完全獨(dú)立的欺旧,他們只是擁有相同的value而已。

2)引用值:在將一個(gè)保存著對(duì)象內(nèi)存地址的變量復(fù)制給另一個(gè)變量時(shí)蛤签,會(huì)把這個(gè)內(nèi)存地址賦值給新變量辞友,

    也就是說(shuō)這兩個(gè)變量都指向了堆內(nèi)存中的同一個(gè)對(duì)象,他們中任何一個(gè)作出的改變都會(huì)反映在另一個(gè)身上震肮。

(這里要理解的一點(diǎn)就是称龙,復(fù)制對(duì)象時(shí)并不會(huì)在堆內(nèi)存中新生成一個(gè)一模一樣的對(duì)象,只是多了一個(gè)保存指向這個(gè)對(duì)象指針的變量罷了)戳晌。多了一個(gè)指針

4鲫尊、參數(shù)傳遞的不同(把實(shí)參復(fù)制給形參的過(guò)程)

首先我們應(yīng)該明確一點(diǎn):ECMAScript中所有函數(shù)的參數(shù)都是按值來(lái)傳遞的。

但是為什么涉及到原始類型與引用類型的值時(shí)仍然有區(qū)別呢沦偎?還不就是因?yàn)閮?nèi)存分配時(shí)的差別疫向。

  1)原始值:只是把變量里的值傳遞給參數(shù),之后參數(shù)和這個(gè)變量互不影響豪嚎。

  2)引用值:對(duì)象變量它里面的值是這個(gè)對(duì)象在堆內(nèi)存中的內(nèi)存地址搔驼,這一點(diǎn)你要時(shí)刻銘記在心!

因此它傳遞的值也就是這個(gè)內(nèi)存地址侈询,這也就是為什么函數(shù)內(nèi)部對(duì)這個(gè)參數(shù)的修改會(huì)體現(xiàn)在外部的原因了舌涨,因?yàn)樗鼈兌贾赶蛲粋€(gè)對(duì)象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扔字,一起剝皮案震驚了整個(gè)濱河市囊嘉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌革为,老刑警劉巖扭粱,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異篷角,居然都是意外死亡焊刹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)虐块,“玉大人俩滥,你說(shuō)我怎么就攤上這事『氐欤” “怎么了霜旧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)儡率。 經(jīng)常有香客問(wèn)我挂据,道長(zhǎng),這世上最難降的妖魔是什么儿普? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任崎逃,我火速辦了婚禮,結(jié)果婚禮上眉孩,老公的妹妹穿的比我還像新娘个绍。我一直安慰自己,他們只是感情好浪汪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布巴柿。 她就那樣靜靜地躺著,像睡著了一般死遭。 火紅的嫁衣襯著肌膚如雪广恢。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天呀潭,我揣著相機(jī)與錄音钉迷,去河邊找鬼。 笑死蜗侈,一個(gè)胖子當(dāng)著我的面吹牛篷牌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踏幻,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼枷颊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了该面?” 一聲冷哼從身側(cè)響起夭苗,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隔缀,沒(méi)想到半個(gè)月后题造,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猾瘸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年界赔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丢习。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡淮悼,死狀恐怖咐低,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袜腥,我是刑警寧澤见擦,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站羹令,受9級(jí)特大地震影響鲤屡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜福侈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一酒来、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧癌刽,春花似錦役首、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)爹袁。三九已至远荠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間失息,已是汗流浹背譬淳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盹兢,地道東北人邻梆。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绎秒,于是被迫代替她去往敵國(guó)和親浦妄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 如何區(qū)分深拷貝與淺拷貝,簡(jiǎn)單點(diǎn)來(lái)說(shuō)玄呛,就是假設(shè)B復(fù)制了A阅懦,當(dāng)修改A時(shí),看B是否會(huì)發(fā)生變化徘铝,如果B也跟著變了耳胎,說(shuō)明這是...
    文朝明閱讀 2,108評(píng)論 0 3
  • 如果您只是想知道如何實(shí)現(xiàn)深拷貝怕午,請(qǐng)直接到頁(yè)面最下方查找實(shí)現(xiàn)方法即可混埠,如果希望了解其中原理,可繼續(xù)往下閱讀诗轻。本文轉(zhuǎn)載...
    易冷zzz閱讀 1,099評(píng)論 0 3
  • 轉(zhuǎn)載于:https://www.cnblogs.com/echolun/p/7889848.html 【JS】深拷...
    馬兒_adcf閱讀 402評(píng)論 0 0
  • 深拷貝和淺拷貝這個(gè)問(wèn)題在面試中常常被問(wèn)到钳宪,而在實(shí)際開(kāi)發(fā)中,只要稍有不慎扳炬,就會(huì)在這里出現(xiàn)問(wèn)題吏颖。尤其對(duì)于初學(xué)者來(lái)說(shuō),我...
    西門(mén)淋雨閱讀 1,786評(píng)論 0 1
  • 陪伴著她長(zhǎng)大恨樟,成長(zhǎng)的過(guò)程中第一件事情就是斷開(kāi)跟媽媽的連接:母乳半醉,也是大家說(shuō)的斷奶。 人真的很奇怪劝术,當(dāng)了媽媽的女人更...
    谷小米閱讀 212評(píng)論 0 0