標籤:測試 lin htm class 情況 答案 result bool 不同
本文主要描述Javascript的資料模型,即對Javascript所支援的資料類型的一個全域概纜。文章比較的理論化,非常深入,因此不易理解,但務必對資料模型有一個映象,因為他是理解Javascript物件模型與Javascript執行模型的基礎。
基本的資料類型
原始類型(單一資料型別、基礎資料型別 (Elementary Data Type))
Undefined類型: 表示聲明了變數但未對其初始化時賦予該變數的值。undefined為Undefined類型下的唯一的一個值。
Null類型:用於表示尚未存在的對象。Null類型下也只有一個專用值null。
Boolean類型:有兩個值true和false,主要用於條件判斷,控制執行流程。
Number類型:代表數字(即包括32的整數,也包括64位的浮點數)
String類型:用於代表字串。
註:關於undefined與null的關係,可以參見《理解Javascript_02_理解undefined和null》一文。
對象:一個無序屬性的集合,這些屬性的值為單一資料型別、對象或者函數。註:這裡對象並不特指全域對象Object.
函數:函數是對象的一種,實現上內部屬性[[Class]]值為"Function",表明它是函數類型,除了對象的內部屬性方法外,還有 [[Construct]]、[[Call]]、[[Scope]]等內部屬性。函數作為函數調用與構造器(使用new關鍵字建立執行個體對象)的處理機制不一樣(Function對象除外),內部方法[[Construct]]用於實現作為構造器的邏輯,方法[[Call]]實現作為函數調用的邏輯。同上,這裡的函數並不特指全域對象Function。
註:關於函數與對象的關係可以引申出很多問題,現在可以不去深究函數實現內部的細節,這將在以後的文章中探討。
註:"基本的資料類型"與"基礎資料型別 (Elementary Data Type)"的概念不一樣,"基本的資料類型"指的是最常用的資料類型,"基礎資料型別 (Elementary Data Type)"指的是原始類型(關於原始類型與參考型別的問題,具體可以參見《理解Javascript_01_理解記憶體配置》一文)。
內建資料類型(內建對象)
Function: 函數類型的使用者介面。
Object: 物件類型的使用者介面。
Boolean, Number, String: 分別為這三種簡單數實值型別的對象封裝器,對象封裝在概念上有點類似C#/Java中的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等單詞的地方,應該迅速的在思維中將它們執行個體化為上面的兩種情況之一。
資料類型實現模型描述
註:圖片來源於http://www.cnblogs.com/riccc
Build-in *** data structure: 指JS內部用於實現***類型的資料結構,由宿主環境(瀏覽器)提供,這些結構我們基本上無法直接操作。
Build-in *** object: 指JS內建的Number, String, Boolean等這些對象,這是JS將內部實現的資料類型暴露給開發人員使用的介面。
Build-in *** constructor: 指JS內建的一些構造器,用來構造相應類型的對象執行個體。它們被封裝成函數對象暴露出來,例如我們可以使用下面的方法訪問到這些函數對象:
123456789101112 |
//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 |
關於"介面"的解釋:簡單的說,介面就是可以調用的方法。如:
12345678 |
//String就是一個介面,它定義了String的行為.它可以由外部調用 var str = new String( ‘笨蛋的座右銘‘ ); //我們自已定義一個介面 function say(msg){ alert(msg); } //調用定義的介面 say( "hello world" ); |
註:完全理解介面的概念需要有一定的強型別語言編程經驗(java/c#),因為本文已經夠複雜了,就不再將問題複雜化了。所以對於介面的答案並不是很嚴謹,但已經夠用了,望高人見諒。
關於單一資料型別的對象化
這是一個細微的地方,下面描述對於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當作函數調用,返回結果會轉換成簡單數實值型別。下面是測試代碼:
1234567891011 |
//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的測試結果。由此也就產生了一個概念"Literal Syntax"
Literal Syntax
在單一資料型別的對象化一節中,我們也看到了簡單類型和其封裝類型可以相互轉換,並且兩者之間的行為相同。但兩者相比較,明顯簡單類型的定義更加輕量,因此我們可以用簡單類型定義替換相應的封裝類型定義。如:
123 |
Number: var i = 100; //替代var i = new Number(100); Boolean: var b = true ; //替代var b = new Boolean(true); String: var str = ‘this is a string.‘ ; //替代var str = new String(‘this is a string‘); |
其實這種類似於var i = 100;var b=true;var str=‘this is a string‘這種定義方式就叫做Literal Syntax。難道就只有單一資料型別才有這種Literal Syntax的表示方法嗎!不是的,複合資料型別同樣有。
123456789101112131415161718192021222324 |
//對象定義的字面量標記法 var obj = {name: ‘笨蛋的座右銘‘ ,age:25} /* //對象的非字面量標記法 var obj = new Object(); obj.name = ‘笨蛋的座右銘‘; obj.age = 25; */ //數組定義的字面量標記法 var arr = [ ‘笨蛋的座右銘‘ ,25]; /* //數組的非字面量標記法 var arr = new Array(); arr[0]=‘笨蛋的座右銘‘]; arr[1]=25; */ //Regex字面量表式法 var reg = /\d+/; /* //Regex非字面量表式法 var reg = new RegExp("\\d+"); */ |
那函數呢!其實函數的定義已經是Literal Syntax的表示形式了。
在實際工作中,我們建議盡量採用Literal Syntax的形式定義變數,因為這樣更簡單,更高效。
來自於"笨蛋"的建議
雖然文章大部分都是參考的,但是裡面也包含了我很多的體會,因此給出建議:
1.對於初學者而言,需要掌握"基礎的資料類型"與"Literal Syntax"部分,其它部分有個映象即可。
2.文章確實非常深入,並不要求完全掌握,因為其內部涉及到了很多東西,包括物件模型與執行模型。這些內容將在以後的博文中探討。
最後,祝大家有所收穫,共同進步。
參考:
123 |
<a href= "http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.htmlhttp://blog.csdn.net/yangdengfeng2003/archive/2007/01/20/1488513.aspx" >http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html http: //blog.csdn.net/yangdengfeng2003/archive/2007/01/20/1488513.aspx </a> |
理解Javascript_04_資料模型 【轉】