js中的堆內存和棧內存


我們常常會聽說什么棧內存、堆內存,那么他們到底有什么區別呢,在js中又是如何區分他們的呢,今天我們來看一下。

一、棧內存和堆內存的區分

一般來說,棧內存主要用於存儲各種基本類型的變量,包括Boolean、Number、String、Undefined、Null...以及對象變量的指針,這時候棧內存給人的感覺就像一個線性排列的空間,每個小單元大小基本相等,棧內存中的變量一般都是已知大小或者有范圍上限的,算作一種簡單存儲。

堆內存主要負責像對象Object這種變量類型的存儲,堆內存存儲的對象類型數據對於大小這方面,一般都是未知的,(所以這大概也是為什么null作為一個object類型的變量卻存儲在棧內存中的原因)。

來一張圖感受一下:

二、測試

Ⅰ.基本數據類型

        /* 基本數據類型 */
        var a = 1;
        var b = 1;
        console.log(a === b);//true

        var c = '桔子桑';
        var d = '桔子桑';
        console.log(c === d);//true

基本數據類型,因為都是存在棧內存中的,以上面的int為例:

var a = 1;變量 a 存在棧內存中,他的值是基本數據類型(int),自然也是在棧內存中,棧內存有沒有1?沒有那就拿出一塊內存存1,這個變量a指向這塊值為1的棧內存地址;

var b = 1;同理,變量 b 也是在棧內存中的,但是賦值的時候,發現,棧內存有一塊地址存着int型的值1,那么就直接指向這塊棧內存了;

所以最終 a === b 是 true;

Ⅱ.new 關鍵字生成的對象

        /* new關鍵字 */
        var a = new String('桔子桑');
        var b = new String('桔子桑');
        console.log(a === b);//fasle

new關鍵字生成的對象都是存在於堆內存中的,上述代碼中:

var a = new String('桔子桑');變量 a 存在於棧內存中,他的值是一個指針,這個指針指向堆內存中的一個對象!

 附上一段C代碼,方便理解

int  a = 20;    /* 實際變量的聲明 */

int  * ip;            /* 指針變量的聲明 */
 
ip = &a;        /* 在指針變量中存儲 變量a 的地址 */

所以我們應該這么理解:

普通變量的值類型是基本數據類型,指向棧內存中的一塊地址;

引用類型變量的值是指針,指向堆內存中的一塊地址。

Ⅲ.指針的賦值(引用類型)

        /* 指針賦值 */
        var a = new String('桔子桑');
        var b = a;
        console.log(a === b);//true

我們看到,指針型變量 a 的值是一個指針,指向堆內存中一塊地址;

然后 又定義了一個變量 b ,他的值等於 a,a 的值是什么?a 的值是一個指針啊,那么變量 b 就等於這個指針,自然也是指向堆內存的那一塊地址咯。

圖示:

Ⅳ.const關鍵字

我們知道const關鍵字用來定義一個常量,

const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址不得改動。

對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個棧內存地址,因此等同於常量。

但對於復合類型的數據(主要是對象和數組),變量指向的棧內存地址,保存的只是一個棧內存指針,const只能保證這個指針是固定的,至於它指向的數據結構是不是可變的,就完全不能控制了。

所以,const保證的是棧內存這邊變量與其值不能發生改變,所以對於復合類型,指針指向的堆內存中存的數據結構能否改變是左右不了的。

        /* const關鍵字 */
        const a = 1;
        a = 2;

        const b = {
            name:'jack'
        };
        b.name = 'tom';

對於前者,因為常量 a 和他的值都是在棧內存中的,不能更改,手動修改只會報錯:

而對於后者,因為常量 b 的值是一個指針,這個指針由於存在於棧內存,所以他的指向是不能更改的(堆內存地址),但是對應堆內存地址中存的數據結構(存了一個對象)是可以更改的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM