- 論壇徽章:
- 0
|
最近較為關(guān)注JavaScript,主要原因是對動態(tài)語言,及動態(tài)語言的實現(xiàn)比較感興趣.無奈我本是C++起家,靜態(tài)類型觀念已根深蒂固,讓我一下子接受"動態(tài)",還真有些適應(yīng)不過來.也許是當(dāng)時對C++對象模型的熱愛,我首先想到了從對象模型上來看JavaScript,希望讓自己胸中自有丘壑.無意中在網(wǎng)上看到了
http://developer.mozilla.org/
中有一篇文章正合我意.正好晚上部門一起吃飯去,下午也沒有什么工作,翻譯出來和大家共享.
JavaScript核心參考——對象模型的細(xì)節(jié)
基于類的語言VS.基于原型的語言(Class-Based VS. Prototype-Based Language)
基于類的面向?qū)ο蟮恼Z言,諸如Java和C++。它們是建立在兩個概念上并不相同的實體(entity)上:類(classed)和實例(instances)。
- 一個類定義了所有的屬性(在Java中的方法和字段,以及C++中的成員,都可被看作是屬性)。這些屬性描述了一組特定對象(譯注:也就是該類的實例)的特征。類是一個抽象的概念,而不是它所描述的一組對象(即該類實例)的任何特定成員。例如,一個Employee類用來代表該組所有的employee對象.
- 另一個概念,實例(instance)。是一個類(class)的實體(instantiation);也就是class所代表的一組成員中的一個。舉個例子Victoria可以是Employee類的一個實例,表示一個特定的員工的個體。一個實例和生成這個實例的類有著同樣(一個不多,一個不少)的屬性。
基于原型的語言,比如JavaScript就沒有這樣的區(qū)別。它僅僅有一個對象概念,而沒有似于C++中的類和實例的概念。對象作為一個模型(template)來使用,通過該模型可以模塑出一個新對象的初始屬性(譯注:因為該新對象的屬性后期還可以被更改,所以此處稱之為最初屬性)。不管是在創(chuàng)建對象的時候,還是運行時(runtime),任何一個對象都可以指定自己的屬性。(譯注:有別于像C++中必須通過在定義時修改生成該對象的類,來修改該對象的屬性) 除此之外,任何一個對象本身可以作為其它對象的一個原形(Prototype),從而關(guān)聯(lián)到其它對象中,并且允許其它對象共享該對象的屬性。
定義一個類(Defining a class)
在基于類(class-based)的語言中,你可以單獨地定義一個類。在那里你可以指定一個特別的方法,該方法被稱為構(gòu)造函數(shù)(Constructor),用來創(chuàng)建該類的實例。構(gòu)造函數(shù)可以在創(chuàng)建一個實例時指定該實例的初始值,或是執(zhí)行其它必要地處理。你可以用new操作符來調(diào)用構(gòu)造函數(shù)并創(chuàng)建一個類的實例。
JavaScript定義類的過程與其類似,但是JavaScript不會將類型的定義從構(gòu)造函數(shù)中分離出來。相反的,你可以定義一個構(gòu)造函數(shù),并以一組特定的初始化屬性和值(記住,在運行時這些屬性和值都是可以更改的)來創(chuàng)建一個對象。在JavaScript中任何函數(shù)都可以作為構(gòu)造函數(shù)。同樣地你仍舊可以使用new操作符通過構(gòu)造函數(shù)創(chuàng)建一個新的對象。
子類和繼承(Subclassed and Inheritance)
在基于類(class-based)的語言中,你可以通過類的定義來創(chuàng)建類層次(父類,子類等)。在類的定義中,你可以指定該類是已存在的一個類的子類。子類(subclass)可以繼承父類(superclass)所有的屬性。除此而外,還可以新增自己屬性或是修改繼承來的屬性。舉個例子,假設(shè)Employee類只有兩個屬性:name和dept。同時Manager類是Employee類的一個子類,并新增了一個report屬性。這樣的話,Manager類的一個實例將會有三個屬性,分別是:name,dept和report.
JavaScript以另外一種方式實現(xiàn)繼承,你可以為一個構(gòu)造函數(shù)關(guān)聯(lián)原型對象(prototypical object)來實現(xiàn)繼承。同樣地,你也可以創(chuàng)建和上面的Employee-Manager示例,之不過用了一些不同的術(shù)語(terminology).首先,你定義一個Employee的構(gòu)造函數(shù),并指定name和dept屬性。接下來,你再定義Manager屬性,并指定report屬性。最后,你再指定一個新的Employee對象,作為Manager構(gòu)造函數(shù)的原型(prototype)。再此之后,你若創(chuàng)建一個新的Manager對象(通過new操作符),它便會從Employee對象繼承name和dept屬性。
添加和移除屬性(Adding and Removing Properties)
在基于類(class-based)的語言中,一般你在編譯時(compile-time)創(chuàng)建一個類。之后你可能在編譯時實例化該類(譯注:比如C++中的模板類的實例化),也可能是在運行時(run-time)實例化該類。在你定義完一個類之后,你不能再修改該類的屬性的數(shù)目和類型。然而,在JavaScript中,你可以在運行時添加或移除任何對象的屬性。你在給一個對象添加一個屬性時,添加的屬性是作為一組對象的原型。這一組對象從這個原型中一樣可以獲得新的屬性。(原文為:If you add a property to an object that is used as the prototype for a set of objects, the objects for which it is the prototype also get the new property. )
不同點的總結(jié)(Summary of Difference)
下面的表格對一些不同點作了簡單地總結(jié)。在本章的剩余部分,將會詳細(xì)地描述在JavaScript中怎么樣使用構(gòu)造函數(shù)和原型來創(chuàng)建一個類的繼承體系(hierarchy),同時將JavaScript中創(chuàng)建類繼承體系的方法和Java中創(chuàng)建同樣的類繼承體系的方法進(jìn)行比較。
Class-based (Java)
Prototype-based (JavaScript)
類和實例是兩個不同的實體
所有的對象都是實例
以"類型定義"方式來申明一個類;以構(gòu)造函數(shù)來實例化一個類。
以構(gòu)造函數(shù)來定義和創(chuàng)建一組對象
用new操作符來創(chuàng)建單個對象
相同
在"類型定義"中定義一個類是現(xiàn)存的類的子類,以此來構(gòu)建一個繼承體系
將一個對象作為一個原型關(guān)聯(lián)至構(gòu)造函數(shù),以此來構(gòu)建一個繼承體系
繼承類型鏈(class-chain)中的屬性
繼承原型鏈(prototype-chain)中的屬性
"類型定義"指定了該類任何一個實例的所有屬性
構(gòu)建函數(shù)或原型指定一組初始化的屬性.可以動態(tài)地為單個對象或是一組對象添加或是移除屬性
Jerry.Chou
2/1'08
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/11680/showart_474648.html |
|