JavaScript中的堆棧

  • 棧(stack) 棧stack爲自動分配的內存空間,它由系統自動釋放;
  • 堆(heap) 堆heap是動態分配的內存,大小不定也不會自動釋放。
JavaScript 中的變量分爲基本類型和引用類型。
  • 基本類型 (Undefined、Null、Boolean、Number和String)
    基本類型在內存中佔據空間小、大小固定 ,他們的值保存在棧(stack)空間,是按值來訪問
  • 引用類型 (對象、數組、函數)
    引用類型佔據空間大、大小不固定, 棧內存中存放地址指向堆(heap)內存中的對象。是按引用訪問的

以下圖所示:棧內存中存放的只是該對象的訪問地址, 在堆內存中爲這個值分配空間 。 因爲這種值的大小不固定,所以不能把它們保存到棧內存中。但內存地址大小的固定的,所以能夠將內存地址保存在棧內存中。 這樣,當查詢引用類型的變量時, 先從棧中讀取內存地址, 而後再經過地址找到堆中的值。數組

image

當咱們看到一個變量類型是已知的,就分配在棧裏面,好比INT,Double等。其餘未知的類型,好比自定義的類型,由於系統不知道須要多大,因此程序本身申請,這樣就分配在堆裏面。函數

棧內存&堆內存

爲了使程序運行時佔用的內存最小,一般要實現垃圾回收機制。spa

當一個方法執行時,每一個方法都會創建本身的內存棧,在這個方法內定義的變量將會逐個放入這塊棧存裏,隨着方法的執行結束,這個方法的棧存也將天然銷燬了。所以,全部在方法中定義的變量都是放在棧內存中的;3d

當咱們在程序中建立一個對象時,這個對象將被保存到運行時數據區中,以便反覆利用(由於對象的建立成本開銷較大),這個運行時數據區就是堆內存。堆內存中的對象不會隨方法的結束而銷燬,即便方法結束後,這個對象還可能被另外一個引用變量所引用(方法的參數傳遞時很常見),則這個對象依然不會被銷燬,只有當一個對象沒有任何引用變量引用它時,系統的垃圾回收機制纔會在覈實的時候回收它。指針

思考問題code

demo1.
var a = 1;
var b = a;
b = 2;

// 這時a是?

demo1中在變量對象中的數據發生複製行爲時,系統會自動爲新的變量分配一個新值。var b = a執行以後,b雖然從新賦值爲2,可是他們其實已是相互獨立互不影響的值了。對象

demo2.
var m = { a: 1, b: 2 }
var n = m;
n.a = 2;

// 這時m.a的值呢?

demo2中咱們經過var n = m執行一次複製引用類型的操做。引用類型的複製一樣也會爲新的變量自動分配一個新的值保存在變量對象中,但不一樣的是,這個新的值,僅僅只是引用類型的一個地址指針。當地址指針相同時,儘管他們相互獨立,可是在變量對象中訪問到的具體對象其實是同一個。所以當我改變n時,m也發生了變化。這就是引用類型的特性。blog

相關文章
相關標籤/搜索