1. 程式人生 > >簡述資料結構:棧記憶體與堆記憶體的儲存方式 js中的原始值

簡述資料結構:棧記憶體與堆記憶體的儲存方式 js中的原始值

在討論堆疊前,先要明確什麼是原始值、引用值。 1.變數可以存放兩種型別的值: 原始值 和 引用值 2.原始值代表原始資料型別的值,也叫基本資料型別,包括 Number、Stirng、Boolean、Null、Underfined。 3.引用值指的是複合資料型別的值,包括 Object、Function、Array、Date、RegExp。

根據資料型別的的不同,有的變數儲存在棧中,有的儲存在堆中。

對於棧記憶體棧記憶體之間的值是拷貝關係,當改變一個棧的內容,不會影響其它棧的內容,棧與棧是互相不影響的。其取值規則是,先進後出。

所以在棧記憶體中,原始值直接拷貝的是原始值的值。

p.s 棧記憶體中的原始值一旦給定,就不可修改,像a=20,這種操作,系統內部會新開一個棧記憶體,其值為20,記憶體名從1011移到1010。

var a = 10;        
var b = a;
a=20;
//這時候改變

在上面程式中,a變數先取出10,拷貝一份放到b裡面去,此時b的值為10,它是a的副本,這個時候無論是更改a或b,對另一個值無影響。 在這裡插入圖片描述

反過來,堆記憶體和棧記憶體是不一樣的,棧記憶體就好比是儲物格子,怎麼放的就怎麼拿,沒有棧的那種存放順序。

引用值是將其地址存放在棧中,將值存放在對記憶體中,所以在引用值拷貝引用值的時候,得到的是地址。所以當兩個棧記憶體中的地址同時指向堆時,此時改變堆的值,將會影響棧記憶體中兩個變數的值。

var arr = [1,2];        
var arr1 = arr;        
document.write(arr+"<br>");       
document.write(arr.push("3") + "<br />")

在上面程式中arr與arr1的值都被改變了,都為[1,2,3]。這也說明push方法,是直接將收到的引數,按順序插入到arrayObject的尾部,它是直接修改arrayObject,而不是建立一個新的陣列。

如果此時再給arr賦一個新的值,arr1的值是不會變的,相當於開了一個新的記憶體。

在這裡插入圖片描述

總結:

  • 原始變數型別及他們的值儲存在棧中,當吧一個原始變數傳遞給另一個原始變數時,是把一個一段棧空間的內容複製到另一段棧空間,這兩個原始值互相不影響。

  • 引用值是把引用變數的名稱儲存在棧中,但是把其實際物件存在堆中,且存在一個指標有變數名指向儲存在堆中的實際物件,當吧引用物件傳遞給另一個變數時,複製的其實是指向實際物件的指標

    ,此時,若通過方法改變其中一個變數的值,則訪問另一個變數時,其值也會隨之加以改變;但若不通過方法,而是通過重新賦值,此時相當於重新開了一段記憶體,該值的原指標改變 ,則另外一個值不會隨他的改變而改變。

  • Number、Stirng、Boolean、Null、Underfined這些基本資料型別,他們的值直接儲存在棧中;

  • Object、Function、Array、Date、RegExp這些引用型別,他們的引用變數儲存在棧中,通過指標指向儲存在堆中的實際物件