摘要:二這么分的好處就是在于節省內存資源,便于合理回收內存詳解中的深淺復制有了上面的鋪墊,那么我們理解起深淺復制就變得容易的許多。
前言
對于前端開發來說,我們經常能夠遇到的問題就是js的深淺復制問題,通常情況下我們解決這個問題的方法就是用JSON.parse(JSON.Stringify(xx))轉換或者用類似于Inmmutable這種第三方庫來進行深復制,但是我們還是要弄懂其中原理,這樣在開發過程中可以省掉很多的坑。
首先讓我們看幾個例子// eg1(操作原對象對復制對象無影響): var a = "a"; var b =a; a = "c"; console.log(b); // a // eg2(操作原對象對復制對象有影響): var a = { a:"a" }; var b =a; a.a = "c"; console.log(b); // {a:"c"} // eg3(操作原對象對復制對象無影響): var a = { a:"a" }; var b =a.a; a.a = "c"; console.log(b); // a // eg4(操作復制對象對原對象有影響): var a = { a:"a" }; var b = a b.b = "b"; console.log(a); // {a:"a",b:"b"} // eg5(操作復制對象對原對象沒有影響): var a = { a:"a" }; var b = a; b = { b:"b" } console.log(a); // {a:"a"}
想要理解上面例子發生的原因就要從數據類型和堆棧內存開始說起
基本數據類型于引用數據類型js中存在著兩種數據類型:基本數據類型和引用數據類型;
基本數據類型包括:Number、String 、Boolean、Null和Undefined這些常見類型
引用數據類型包括: Object 、Array 、Function這些對象類型
在大多數編程語言中,都存在著這樣的兩個內存空間一個是堆內存(heap),另一個是棧內存(stack)。
當我們存儲一個基本數據類型的時候,我們直接放到棧內存中。而當我們存儲一個引用數據類型的時候,我們將實際內容存儲在堆內存當中,同時在棧內存中存放著該內容的引用,也就是一個指針
為什么我們這么做呢?簡單來說有兩點,一是因為棧內存中存放大小固定的數據,即基本數據類型的數據,同時引用數據類型的指針也是大小固定的,也可以放進棧內存中,方便程序查找這個數據;而堆內存中存放的是大小不固定的數據,所以適合存放引用數據類型。二這么分的好處就是在于節省內存資源,便于os合理回收內存
有了上面的鋪墊,那么我們理解起深淺復制就變得容易的許多。
首先我們要記住:當我們復制一個基本數據類型的數據時,是新建一個數據同時存放到棧內存中,而當我們復制一個引用數據類型時,是復制這個引用數據類型的地址,存放到棧內存中,此時堆內存中并沒有任何變化
讓我們來看之前的例子
例一和例二就沒什么好說的了,我們從例三開始:
a.a是一個字符串類型,是基本類型,所以當b復制的時候是直接復制了一個存放到棧內存中,當a改變時,對b沒有影響
例四:
a是一個對象,是引用數據類型,所以當b復制的時候是復制了a的指針,當對a和b操作時,仍然操作的是堆內存中同一對象,所以a會發生改變
例五:
這個例子看似和上面的很像但實際有很大不同,b = {b:"b"}這個操作實際上是新建了一個對象
也就是說在堆內存中新建了一個地方,來存放{b:"b"}同時將棧內存中b原來存儲的指向a的指針指向了這個對象,多以a并未發生任何改變
https://segmentfault.com/a/11...(重點看這篇,寫的很好!)
http://blog.csdn.net/flyingpi...
https://www.cnblogs.com/cxyin...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107109.html
摘要:中有三種數據結構棧堆隊列。前端進擊的巨人一執行上下文與執行棧,變量對象中解釋執行棧時,舉了一個乒乓球盒子的例子,來演示棧的存取方式,這里再舉個栗子搭積木。對于基本類型,棧中存儲的就是它自身的值,所以新內存空間存儲的也是一個值。 面試經常遇到的深淺拷貝,事件輪詢,函數調用棧,閉包等容易出錯的題目,究其原因,都是跟JavaScript基礎知識不牢固有關,下層地基沒打好,上層就是豆腐渣工程,...
摘要:基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數據。它會拋棄對象的。另外,查資料過程中還看到這么一個詞結構化克隆算法還有這一篇資料也有參考,也寫得比較詳細了的深淺拷貝 基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數據。 淺拷貝對于字符串來說,是值的復制,而對于對象來說則是對對象地址的復制;而深拷貝的話,它不...
摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內存就有兩個指針指向堆內存同一個數據。結果如下擴展運算符只能對一層進行深拷貝如果拷貝的層數超過了一層的話,那么就會進行淺拷貝那么我們可以看到和展開原算符對于深淺拷貝的結果是一樣。 JS中數據類型 基本數據類型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用數據類型:...
閱讀 1470·2019-08-30 15:55
閱讀 1172·2019-08-30 15:52
閱讀 1282·2019-08-29 13:53
閱讀 1465·2019-08-29 11:19
閱讀 2964·2019-08-26 13:29
閱讀 527·2019-08-26 11:33
閱讀 2587·2019-08-23 17:20
閱讀 1021·2019-08-23 14:14