js的堆和棧

1、介紹

創建數據的時候就會佔用內容、內存主要開闢了兩類空間
1. 堆(進程,線程共享)

  • 大小不固定,可隨時增加
  • 不允許js直接訪問堆內存
  • 存儲引用數據類型
  • 按引用訪問
  • 存儲的值大小不定,可動態調整
  • 主要用來存放對象
  • 空間大,但是運行效率相對較低
  • 無序存儲,可根據引用直接獲取
    2. 棧(線程)
  • 創建的時候就確定了大小,故可能會溢出
  • 按照順序存放 先進後出
  • 存儲基礎數據類
  • 按值訪問
  • 存儲的值大小固定
  • 由系統自動分配內存空間
  • 空間小,運行效率高
  • 棧中的DOM,ajax,setTimeout會依次進入到隊列中,當棧中代碼執行完畢後,再將隊列中的事件放到執行棧中依次執行。

複雜數據類型(Object、[數組、對象])創建的時候 開闢的 堆內存
基本數據類型(number、string等6種)創建的時候 開闢的 棧內容

2、比較

var str=new String('abc');
var str='abc';

同樣是創建兩個字符串,第一種是用new關鍵字來新建String對象,對象會存放在堆中,每調用一次就會創建一個新的對象;

而第二種是在棧中,棧中存放值‘abc’和對值的引用。推薦使用第二種方式創建多個’abc’字符串,這種寫法在內存中只存在一個值,有利於節省內存空間。

同時它可以在一定程度上提高程序的運行速度,因爲存儲在棧中,其值可以共享,並且由於棧訪問更快,所以對於性能的提高大有裨益。

而第一種方式每次都在堆中創建一個新的String對象,而不管其字符串值是否相等及是否有必要創建新對象,從而加重了程序的負擔。並且堆的訪問速度慢,對程序性能的影響也大。

另外,出於邏輯運算的考慮,當對兩個變量進行比較時,使用堆和棧存儲就會有差異

1) 例如下面的代碼,實際只比較棧中的值:

var str1='abc';
var str2='abc';
alert(str1==str2); // true
alert(str1===str2); // true
不管是邏輯等於和邏輯全等運算都返回true,可以看出str1和str2指向同一個值。

2)例如下面的代碼,實際只比較堆中的值:

var str1=new String('abc');
var str2=new String('abc');
alert(str1==str2); // false
alert(str1===str2); // false
不管是邏輯等於還是邏輯全等都返回false,可以看出str1和str2指向的不是同一個對象。

3)例如下面的代碼,比較堆和棧中的值:

var str1=new String('abc');
var str2='abc';
alert(str1==str2); // true
alert(str1===str2); // false
在進行邏輯等於和邏輯全等運算時,會首先將變量轉成相同的數據類型,然後進行對比。變量str1和str2的數據類型雖然不同,但比較運算還是返回true。但邏輯全等運算與邏輯等於運算不同,它會對數據類型進行比較,看是否是引用的同一個數據。

3、總結

  • 棧內存是有限度的可以自動釋放,堆內存無限不會自動釋放,運行程序的時候,每個線程分配一個棧,每個進程分配一個堆
  • 棧存放基本類型的變量、函數、對象變量指針,堆存放對象
  • 放在棧裏面的變量,只要值一樣就可以全等,棧佔內存較小,會自動釋放值,值爲null,放在堆裏面的變量,值相等(應爲會默認轉成相同數據類型進行對比),全等=會比較是否引用一個數據故不等,不會自動釋放值
  • 棧中數據可以共享,若是兩個變量值一樣,可以一起指向那個值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章