1. 程式人生 > >js棧記憶體和堆記憶體的區別

js棧記憶體和堆記憶體的區別

首先JavaScript中的變數分為基本型別和引用型別。基本型別就是儲存在棧記憶體中的簡單資料段,而引用型別指的是那些儲存在堆記憶體中的物件。

1、基本型別

基本型別有Undefined、Null、Boolean、Number 和String。這些型別在記憶體中分別佔有固定大小的空間,他們的值儲存在棧空間,我們通過按值來訪問的。

2、引用型別

引用型別,值大小不固定,棧記憶體中存放地址指向堆記憶體中的物件。是按引用訪問的。如下圖所示:棧記憶體中存放的只是該物件的訪問地址,在堆記憶體中為這個值分配空間由於這種值的大小不固定,因此不能把它們儲存到棧記憶體中。但記憶體地址大小的固定的,因此可以將記憶體地址儲存在棧記憶體中。 這樣,當查詢引用型別的變數時, 先從棧中讀取記憶體地址, 然後再通過地址找到堆中的值。對於這種,我們把它叫做按引用訪問

   當我們看到一個變數型別是已知的,就分配在棧裡面,比如INT,Double等。其他未知的型別,比如自定義的型別,因為系統不知道需要多大,所以程式自己申請,這樣就分配在堆裡面。基本型別大小固定,引用型別大小不固定,分開存放使得程式執行佔用記憶體最小。

3、棧記憶體:存放基本型別。 堆記憶體:存放引用型別(在棧記憶體中存一個基本型別值儲存物件在堆記憶體中的地址,用於引用這個物件。)

4、基本型別在當前執行環境結束時銷燬,而引用型別不會隨執行環境結束而銷燬,只有當所有引用它

的變數不存在時這個物件才被垃圾回收機制回收。

**********************************************************************

看一個例子:

var x = {name:"aaa"};//初始化一個物件

var obj1 = x;

var obj2 = x; //obj1,obj2指向同一個引用型別

obj1.name = "bbb"; //在原引用上修改物件屬性,x,obj,obj2的name屬性值均改變

obj1 = {name:"bbb"} //給obj1賦了一個新的引用,所以只有obj的name值改變了