摘要:二這么分的好處就是在于節(jié)省內(nèi)存資源,便于合理回收內(nèi)存詳解中的深淺復(fù)制有了上面的鋪墊,那么我們理解起深淺復(fù)制就變得容易的許多。
前言
對(duì)于前端開(kāi)發(fā)來(lái)說(shuō),我們經(jīng)常能夠遇到的問(wèn)題就是js的深淺復(fù)制問(wèn)題,通常情況下我們解決這個(gè)問(wèn)題的方法就是用JSON.parse(JSON.Stringify(xx))轉(zhuǎn)換或者用類似于Inmmutable這種第三方庫(kù)來(lái)進(jìn)行深復(fù)制,但是我們還是要弄懂其中原理,這樣在開(kāi)發(fā)過(guò)程中可以省掉很多的坑。
首先讓我們看幾個(gè)例子// eg1(操作原對(duì)象對(duì)復(fù)制對(duì)象無(wú)影響): var a = "a"; var b =a; a = "c"; console.log(b); // a // eg2(操作原對(duì)象對(duì)復(fù)制對(duì)象有影響): var a = { a:"a" }; var b =a; a.a = "c"; console.log(b); // {a:"c"} // eg3(操作原對(duì)象對(duì)復(fù)制對(duì)象無(wú)影響): var a = { a:"a" }; var b =a.a; a.a = "c"; console.log(b); // a // eg4(操作復(fù)制對(duì)象對(duì)原對(duì)象有影響): var a = { a:"a" }; var b = a b.b = "b"; console.log(a); // {a:"a",b:"b"} // eg5(操作復(fù)制對(duì)象對(duì)原對(duì)象沒(méi)有影響): var a = { a:"a" }; var b = a; b = { b:"b" } console.log(a); // {a:"a"}
想要理解上面例子發(fā)生的原因就要從數(shù)據(jù)類型和堆棧內(nèi)存開(kāi)始說(shuō)起
基本數(shù)據(jù)類型于引用數(shù)據(jù)類型js中存在著兩種數(shù)據(jù)類型:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型;
基本數(shù)據(jù)類型包括:Number、String 、Boolean、Null和Undefined這些常見(jiàn)類型
引用數(shù)據(jù)類型包括: Object 、Array 、Function這些對(duì)象類型
在大多數(shù)編程語(yǔ)言中,都存在著這樣的兩個(gè)內(nèi)存空間一個(gè)是堆內(nèi)存(heap),另一個(gè)是棧內(nèi)存(stack)。
當(dāng)我們存儲(chǔ)一個(gè)基本數(shù)據(jù)類型的時(shí)候,我們直接放到棧內(nèi)存中。而當(dāng)我們存儲(chǔ)一個(gè)引用數(shù)據(jù)類型的時(shí)候,我們將實(shí)際內(nèi)容存儲(chǔ)在堆內(nèi)存當(dāng)中,同時(shí)在棧內(nèi)存中存放著該內(nèi)容的引用,也就是一個(gè)指針
為什么我們這么做呢?簡(jiǎn)單來(lái)說(shuō)有兩點(diǎn),一是因?yàn)闂?nèi)存中存放大小固定的數(shù)據(jù),即基本數(shù)據(jù)類型的數(shù)據(jù),同時(shí)引用數(shù)據(jù)類型的指針也是大小固定的,也可以放進(jìn)棧內(nèi)存中,方便程序查找這個(gè)數(shù)據(jù);而堆內(nèi)存中存放的是大小不固定的數(shù)據(jù),所以適合存放引用數(shù)據(jù)類型。二這么分的好處就是在于節(jié)省內(nèi)存資源,便于os合理回收內(nèi)存
有了上面的鋪墊,那么我們理解起深淺復(fù)制就變得容易的許多。
首先我們要記?。?strong>當(dāng)我們復(fù)制一個(gè)基本數(shù)據(jù)類型的數(shù)據(jù)時(shí),是新建一個(gè)數(shù)據(jù)同時(shí)存放到棧內(nèi)存中,而當(dāng)我們復(fù)制一個(gè)引用數(shù)據(jù)類型時(shí),是復(fù)制這個(gè)引用數(shù)據(jù)類型的地址,存放到棧內(nèi)存中,此時(shí)堆內(nèi)存中并沒(méi)有任何變化
讓我們來(lái)看之前的例子
例一和例二就沒(méi)什么好說(shuō)的了,我們從例三開(kāi)始:
a.a是一個(gè)字符串類型,是基本類型,所以當(dāng)b復(fù)制的時(shí)候是直接復(fù)制了一個(gè)存放到棧內(nèi)存中,當(dāng)a改變時(shí),對(duì)b沒(méi)有影響
例四:
a是一個(gè)對(duì)象,是引用數(shù)據(jù)類型,所以當(dāng)b復(fù)制的時(shí)候是復(fù)制了a的指針,當(dāng)對(duì)a和b操作時(shí),仍然操作的是堆內(nèi)存中同一對(duì)象,所以a會(huì)發(fā)生改變
例五:
這個(gè)例子看似和上面的很像但實(shí)際有很大不同,b = {b:"b"}這個(gè)操作實(shí)際上是新建了一個(gè)對(duì)象
也就是說(shuō)在堆內(nèi)存中新建了一個(gè)地方,來(lái)存放{b:"b"}同時(shí)將棧內(nèi)存中b原來(lái)存儲(chǔ)的指向a的指針指向了這個(gè)對(duì)象,多以a并未發(fā)生任何改變
https://segmentfault.com/a/11...(重點(diǎn)看這篇,寫(xiě)的很好?。?br>http://blog.csdn.net/flyingpi...
https://www.cnblogs.com/cxyin...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/107109.html
摘要:從而也引出了所謂的深淺復(fù)制問(wèn)題。附注對(duì)于淺復(fù)制,其實(shí)還有其他的實(shí)現(xiàn)方式,比如數(shù)組中和方法,對(duì)于這些還是希望大家自己了解,本本主要針對(duì)深淺復(fù)制的實(shí)現(xiàn)原理進(jìn)行解析。 前言 在之前寫(xiě)繼承的過(guò)程談到了深淺復(fù)制的問(wèn)題,因?yàn)橛凶x者反映到需要解析,趁今天周末寫(xiě)一篇解析,今天的主體相對(duì)之前來(lái)說(shuō)理解難度低一些,篇幅可能也比較短,諸君按需閱讀即可。 從兩種數(shù)據(jù)類型說(shuō)起 在js中,變量的類型可以大致分成兩種...
摘要:中有三種數(shù)據(jù)結(jié)構(gòu)棧堆隊(duì)列。前端進(jìn)擊的巨人一執(zhí)行上下文與執(zhí)行棧,變量對(duì)象中解釋執(zhí)行棧時(shí),舉了一個(gè)乒乓球盒子的例子,來(lái)演示棧的存取方式,這里再舉個(gè)栗子搭積木。對(duì)于基本類型,棧中存儲(chǔ)的就是它自身的值,所以新內(nèi)存空間存儲(chǔ)的也是一個(gè)值。 面試經(jīng)常遇到的深淺拷貝,事件輪詢,函數(shù)調(diào)用棧,閉包等容易出錯(cuò)的題目,究其原因,都是跟JavaScript基礎(chǔ)知識(shí)不牢固有關(guān),下層地基沒(méi)打好,上層就是豆腐渣工程,...
摘要:在之前的文章專題之?dāng)?shù)據(jù)類型和類型檢測(cè)中我有講過(guò),中的數(shù)據(jù)類型分為兩種,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結(jié)構(gòu)中的是按值訪問(wèn),所以不存在深淺拷貝問(wèn)題。 前言 在開(kāi)發(fā)過(guò)程中,偶爾會(huì)遇到這種場(chǎng)景,拿到一個(gè)數(shù)據(jù)后,你打算對(duì)它進(jìn)行處理,但是你又希望拷貝一份副本出來(lái),方便數(shù)據(jù)對(duì)比和以后恢復(fù)數(shù)據(jù)。 那么這就涉及到了 JS 中對(duì)數(shù)據(jù)的深淺拷貝問(wèn)題,所謂深淺拷貝,淺拷貝的意思就是,...
摘要:基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì),這類引用類型數(shù)據(jù)。它會(huì)拋棄對(duì)象的。另外,查資料過(guò)程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫(xiě)得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì)Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對(duì)于字符串來(lái)說(shuō),是值的復(fù)制,而對(duì)于對(duì)象來(lái)說(shuō)則是對(duì)對(duì)象地址的復(fù)制;而深拷貝的話,它不...
摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。結(jié)果如下擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝那么我們可以看到和展開(kāi)原算符對(duì)于深淺拷貝的結(jié)果是一樣。 JS中數(shù)據(jù)類型 基本數(shù)據(jù)類型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用數(shù)據(jù)類型:...
閱讀 1533·2019-08-30 15:55
閱讀 1241·2019-08-30 15:52
閱讀 1354·2019-08-29 13:53
閱讀 1512·2019-08-29 11:19
閱讀 3057·2019-08-26 13:29
閱讀 642·2019-08-26 11:33
閱讀 2674·2019-08-23 17:20
閱讀 1089·2019-08-23 14:14