說到Javascript的內建類型,已知的有 Boolean Number String Object RegExp Function Array Date Undefined Null 。
但,
真的就這麼多麼?
其實還有3個類型
這3個類型是Javascript執行器使用的類型,它們不能在代碼中直接使用。
瞭解它們可以讓你的代碼更出色。
這三個類型分別是 Reference List Activation 。
List 是最好理解的,它們用於儲存多個值的列表。
我們知道,在函數被執行的時候, 可以使用 arguments 來擷取當前的參數。
但是,
arguments 是什麼類型 ?
Object ? ---- 通過Javascript代碼可以認為它是 Object 。
不過, arguments 又和數組一樣,可以使用索引和 length , 它又可以是 Array 類型。
其實,
arguments 的類型就是 List 。
List類型用來儲存臨時的參數列表。
Reference 是引用。
Reference 有2個屬性,分別是 Base 和 PropertyName ,它表示一個對象的某個屬性名稱字的引用。
系統執行的時候,需要一個空間儲存上代碼執行的傳回值。 比如執行如下代碼 : 2 + 4 後, 儲存的傳回值是 Number:6
當執行這樣的代碼時,obj.prop 儲存的傳回值不是 obj.prop 對應的值。
在js中,假如某個對象的某屬性不存在,不會報錯。如果 obj.prop 執行之後儲存傳回值,則肯能出錯,因為 obj.prop 可作為左值,比如
obj.prop = 2;
這時 obj.prop 是運算式,但作為左值使用, 如果儲存傳回值,那 obj.prop = undefine .最後就是 undefined = 2 , 這樣是不行的。
所以 js內部有個 Reference , obj.prop 返回的是 Reference 執行個體 ( Base-> obj PropertyName -> prop)
Base 可以是任何變數,當Base 是全域變數時, 如果 PropertyName 不存在, Reference 會報錯。即
var a = b; // b 是全域對象, 運算式 b 執行後,返回 Reference( Base -> window ProperyName -> b)
因為 Base 是全域對象,並 找不到 b 屬性, 所以報錯。相信細心的你可以發現, Javascript 在出現找不到變數的時候,拋出的是 ReferenceError 錯誤。
try{
var v = sth;
}catch(e){
alert(e);
}
最後一個是 Activation 。 其實它是隱藏地最好的。
Javascript的所有變數都是屬於某一個對象的。比如全域變數屬於 window 。 那被閉包的變數呢?
每個函數執行時,會產生內部變數的一個閉包。
function by_xuld() {
var obj = new Object();
return obj;
}
alert(by_xuld() === by_xuld());
實驗證明,同個函數在每次執行的時候,都會建立一個 obj 的變數。那 obj變數是如何儲存的?
是不是一個函數就有一個儲存內部的變數的空間?
當然不是, 如果一個函數自己有儲存變數的位置, 那麼同個函數不肯能出現2個不同的變數。
其實,每個函數在執行的時候,就會建立一個臨時的範圍,所有的內部變數都儲存成這個 範圍的屬性。 比如函數內的 var 定義的, 這個範圍本質是 Activation 類型的一個變數。 無法用Javascript 訪問這個變數自己,但可以訪問這個變數的屬性。(注意 Activation 是範圍, 不是 this 指向 )
當函數內部執行了 var obj ; obj; 時 , 最後返回的是 Reference 對象, 其 Base 是 Activation 。
這3個類似是Js執行器必須的。 知道這幾個類型之後,你就可以知道:
閉包的原理
類型容錯原理 ( 為什麼 typeof a 當a 沒定義 不出錯 )