深刻理解javascript系列(二):內存空間

由於javascript有GC存在,因此內存空間並非被咱們重視。王立大神說"理解內存空間,就是成爲大牛的開始"。因此咱們頗有必要學習和理解內存空間。javascript

2.1  基礎數據類型與變量對象

最新的ECMAScript標準定義了7中數據類型,其中就包括6中基本數據與一種引用數據類型(object)前端

其中基礎數據類型如圖所示:java


下面來探討一個問題,有一個很簡單的例子以下所示:面試

function fn() {
    var a1 = 10;
    var a2 = 'hello';
    var a3 = null;
}複製代碼

如今須要思考的是當fn()的時候,局部變量a1它們都保存在什麼地方?算法

函數運行時,會建立一個執行環境這個執行環境叫作執行上下文(Execution Context)。在執行上下文中,會建立一個叫作變量對象(VO)的東西。基礎類型都保存在這裏了。bash


變量對象也存在與堆內存中,可是因爲變量對象有特殊的功能,因此咱們仍是儘可能將它與堆內存區別看待。函數

2.2  引用數據類型與堆內存空間

引用數據類型(Object)的值是保存在堆內存中的。可是咱們以前也講過,在javascript中,不容許直接操做堆內存。因此操做對象時,其實是操做對象的引用。所以引用數據類型都是按引用訪問的。這裏的引用,能夠理解爲保存在變量對象中的一個地址,該地址與堆內存中的對象相關聯。學習

爲了更好地理解變量對象與堆內存,下面用一個例子與圖解配合講解。spa

function foo() {
    var a1 = 10;
    var a2 = 'hello';
    var a3 = null;
    var b = { m: 20};
    var c = [1,2,3];
}複製代碼

再來重複一次。函數運行時,會建立一個執行環境,咱們把這個執行環境稱爲執行上下文。在執行上下文中,會建立一個變量對象(VO)。基本數據類型的值每每都保存在變量對象中。指針

以下圖所示,當咱們想要訪問堆內存空間中的引用數據類型時,其實是經過引用(地址指針)來訪問的。


在前端面試中,咱們經常會遇到這樣一個相似的問題。

//demo01.js
var a = 20;
var b = a;
b = 30;
console.log(a); // a ? 這時a的值多少複製代碼

//demo02.js
var m = { a:10, b:20};
var n = m;
n.a = 15;
//這時m.a的值是多少?複製代碼

當變量對象中的數據發生複製行爲時,新的變量會被分配一個新的值。因此基本數據類型只是複製了一個,而引用數據類型了不光是複製了同一個引用地址,而且指向同一個地方。

2.3  內存空間管理

由於GC的存在,使得咱們在開發時好像並不用那麼關心內存的使用問題,內存的分配與回收徹底實現了自動管理(但這並不表明他不會泄漏)。陽波大神說:「瞭解內存機制有助於本身清晰地認知到本身寫的代碼在執行過程當中都發生了什麼,從而寫出更優秀的代碼。」

var a = 20;
alert(a + 100);
a = null;複製代碼

上面的三條語句,分別對應以下三個過程。

一、分配內存;

二、使用分配到的內存

三、不須要時銷燬內存

1與2都好理解。這裏主要講下3.

javascript的垃圾回收主要是依靠"引用"的概念。當一塊內存空間中數據可以被訪問時,垃圾回收器會認爲他是可以「被得到的」。不可以被得到的數據,就會被打上標記,而且被回收內存空間,這種方式叫作標記-清除算法。

相關文章
相關標籤/搜索