基礎資料型別 (Elementary Data Type)
基礎資料型別 (Elementary Data Type)是JS語言最底層的實現。
簡單數實值型別: 有Undefined, Null, Boolean, Number和String。注意,描述中的英文單詞在這裡僅指資料類型的名稱,並不特指JS的全域對象N an, Boolean, Number, String等,它們在概念上的區別是比較大的。
對象: 一個無序屬性的集合,這些屬性的值為簡單數實值型別、對象或者函數。同上,這裡的對象並不特指全域對象Object。
函數: 函數是對象的一種,實現上內部屬性[[Class]]值為"Function",表明它是函數類型,除了對象的內部屬性方法外,還有[[Construct]]、[[Call]]、[[Scope]]等內部屬性。函數作為函數調用與構造器(使用new關鍵字建立執行個體對象)的處理機制不一樣(Function對象除外),內部方法[[Construct]]用於實現作為構造器的邏輯,方法[[Call]]實現作為函數調用的邏輯。同上,這裡的函數並不特指全域對象Function。
函數在JS這個Prototype語言中可以看作是物件導向語言的類,可以用它來構造對象執行個體。既然函數可以看作是類,所以每一個函數可以看作是一種擴充資料類型。
內建資料類型(內建對象)
Function: 函數類型的使用者介面。
Object: 物件類型的使用者介面。
Boolean, Number, String: 分別為這三種簡單數實值型別的對象封裝器,對象封裝在概念上有點類似C#中的Box/Unbox。
Date, Array, RegExp: 可以把它們看作是幾種內建的擴充資料類型。
首先,Function, Object, Boolean, Number, String, Date, Array, RegExp等都是JavaScript語言的內建對象,它們都可以看作是函數的衍生類別型,例如Number instanceof Function為true,Number instanceof Object為true。在這個意義上,可以將它們跟使用者定義的函數等同看待。
其次,它們各自可以代表一種資料類型,由JS引擎用native code或內建的JS代碼實現,是暴露給開發人員對這些內建資料類型進行操作的介面。在這個意義上,它們都是一種抽象的概念,後面隱藏了具體的實現機制。
在每一個提到Number, Function等單詞的地方,應該迅速的在思維中將它們執行個體化為上面的兩種情況之一。
資料類型實現模型描述
Build-in *** data structure: 指JS內部用於實現***類型的資料結構,這些結構我們基本上無法直接操作。
Build-in *** object: 指JS內建的Number, String, Boolean等這些對象,這是JS將內部實現的資料類型暴露給開發人員使用的介面。
Build-in *** constructor: 指JS內建的一些構造器,用來構造相應類型的對象執行個體。它們被封裝成函數對象暴露出來,例如我們可以使用下面的方法訪問到這些函數對象:
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
//access the build-in number constructor
var number = new Number(123);
var numConstructor1 = number.constructor; //or
var numConstructor2 = new Object(123).constructor;
//both numConstructor1 and numConstructor2 are the build-in Number constructor
numConstructor1 == numConstructor2 //result: true
//access the build-in object constructor
var objConstructor1 = {}.constructor; //or
var objConstructor2 = new Object().constructor;
//both objConstructor1 and objConstructor2 are the build-in Object constructor
objConstructor1==objConstructor2 //result: true
具體實現上,上圖中橫向之間可能也存在關聯,例如對於build-in data structure和constructor,Function、 Date、 Array、 RegExp等都可以繼承Object的結構而實現,但這是具體實現相關的事情了。
關於簡單數實值型別的對象化
這是一個細微的地方,下面描述對於Boolean, String和Number這三種簡單數實值型別都適用,以Number為例說明。
JS規範要求: 使用var num1=123;這樣的代碼,直接返回基礎資料型別 (Elementary Data Type),就是說返回的對象不是派生自Number和Object類型,用num1 instanceof Object測試為false;使用new關鍵字建立則返回Number類型,例如var num2=new Number(123); num2 instanceof Number為true。
將Number當作函數調用,返回結果會轉換成簡單數實值型別。下面是測試代碼:
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
var num1 = new Number(123); //num1 derived from Number & Object
num1 instanceof Number //result: true
num1 instanceof Object //result: true
//convert the num1 from Number type to primitive type, so it's no longer an instance of Number or Object
num1 = Number(num1);
num1 instanceof Number //result: false
num1 instanceof Object //result: false
var num2 = 123; //num2 is a primitive type
num2 instanceof Number //result: false
num2 instanceof Object //result: false
雖然我們得到了一個簡單數實值型別,但它看起來仍然是一個JS Object對象,具有Object以及相應類型的所有屬性和方法,使用上基本沒有差別,唯一不同之處是instanceof的測試結果。
Prototype繼承
Prototype