1. 程式人生 > >JavaScript中變量、作用域和內存問題(JavaScript高級程序設計第4章)

JavaScript中變量、作用域和內存問題(JavaScript高級程序設計第4章)

外部 對象的引用 pan object 揮手 fun 可用內存 限制 argument

一、變量

(1)ECMAScript變量肯能包含兩種不同的數據類型的值:基本類型值和引用類型值基本類型值指的是簡單的數據段,引用類型值指那些可能由多個值構成的對象。

(2)基本數據類型是按值訪問,可以操作保存在變量中的實際的值;引用類型的值是保存在內存中對象,操作對象時,實際上是在操作對象的引用而不是實際的對象,引用類型的值是按引用訪問的。

技術分享

(3)傳遞參數。ECMScript中所有的函數的參數都是按值傳遞的。

function setName(obj){
     obj.name = "Nicholas";
     obj = new Object();   //理解為新建一個對象,這個對象和參數obj的值不同,即在堆中地址不同,堆中值也不同,不是同一個對象
     obj.name = "Greg";   //函數執行完後,新建的obj被銷毀。
}

var person = new Object();
setName(person);
alert(person.name);   //"Nicholas"

當在函數內部重寫obj時,這個變量引用的就是一個局部對象了。而這個局部對象會在函數執行完畢後立即被銷毀。

(4)instanceof操作符 如果變量時給定引用類型的實例,那麽instanceof操作符始終會返回true;如果使用instanceof操作符檢測基本類型的值,則操作符始終返回false;因為基本類型不是對象。

二、執行環境及作用域

(1)執行環境是JavaScript中最為重要的一個概念。執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都保存在這個對象中。

全局執行環境是最外圍的一個執行環境。在web瀏覽器中,全局執行環境被認為是window對象。

當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈。作用域鏈的作用是保證對執行環境有權訪問的所有變量和函數的有序訪問。作用域鏈的前端,始終都是當前執行的代碼所在環境的變量對象。如果這個環境是函數,則將其活動對象作為變量對象。活動對象在最開始時只包含一個變量,即arguments對象(這個對象在全局環境中是不存在的)。全局執行環境的變量對象始終都是作用域鏈中的最後一個對象。

(2)沒有塊級作用域

if(true){
    
   var color = "blue";
}
alert(color);   //blue;



for(vari = 0; i < 10;i++){
  doSomething(i);

}
alert(i);   
//10;

對於JavaScript來說,由for語句創建的變量 i 即使在for循環執行結束後,也依舊會存在於循環外部的執行環境中。

三、垃圾收集

(1)JavaScript具有自動垃圾收集機制。這種垃圾收集機制的原理其實很簡單:找出那些不再繼續使用的變量,然後釋放其占用的內存。

JavaScript中最常用的垃圾收集方式是標記清除。垃圾收集器在運行的時候會給存儲在內存中的所有變量都加上標記。然後,它會去掉環境中的變量以及被環境中的變量引用的變量的標記。而在此之後再被加上標記的變量將被視為準備刪除的變量。

另一種不太常見的垃圾收集策略叫做引用計數。

(2)管理內存

JavaScript在進行內存管理及垃圾收集時面臨的問題還是有點與眾不同。其中最主要的一個問題,就是分配給web瀏覽器的可用內存數量通常要比分配給桌面應用程序的少。這樣做的目的主要是出於安全方面考慮,目的是防止運行JavaScript的網頁耗盡全部系統內存而導致系統崩潰。內存限制問題不僅會影響給變量分配內存,同時還會影響調用棧以及在一個線程中能夠同時執行的語句數量。

優化內存占用的最佳方式,就是為執行中的代碼值保存必要的數據。一旦數據不再有用,最好通過將其值設置為null來釋放其引用——這個做法叫做解除引用

。這一做法使用於大多數全局變量和全局對象的屬性。

function createPerson(name){

     var localPerson = new Object();
     localPerdon.name = name;
     return localPerson;

}

var globalPerson = createPerson("Nicholas");

//手工解除globalPerson的引用
globalPerson = null;

解除一個值的引用並不意味著自動揮手該值所占用的內存。解除引用的真正作用是讓值脫離執行環境,以便垃圾收集器下次運行時將其回收。

JavaScript中變量、作用域和內存問題(JavaScript高級程序設計第4章)