?
?
Quiz1 |
?
Javascript中存在“類”么?
?
萬物皆對象
Javascript中除了基本數(shù)據(jù)(Undefined、Null、Boolean、Number、String),其他都是對象(Object)。
實際上,Javascript中的對象是數(shù)據(jù)與功能的集合。例如我們知道:
var foo = new Function("alert('hello world!')" ); foo();
可見foo是一個函數(shù),也是一種對象。再比如說:
function foo(){ // do something } foo.data = 123 ; foo[ "data2"] = "hello" ; alert(foo.data); alert(foo.data2);
函數(shù)也可以像對象一樣添加屬性。
?
對象的構建
一般我們用構造函數(shù)來構建對象,但如果沒有構造函數(shù),我們也有辦法構建我們想要的對象:
function creatPerson(__name, __sex, __age){ return { name: __name, sex: __sex, age: __age, get: function (__key){ alert( this [__key]); } }; } var Bob = creatPerson("Bob", "male", 18 ); Bob.get( "name"); // Bob Bob.get("sex"); // male Bob.get("age"); // 18
但是這不夠,我希望方法是可以共享的。比如我再用該函數(shù)創(chuàng)建一個Tom對象,get函數(shù)就又被創(chuàng)建了一次,這明顯地浪費了我的內(nèi)存。
?
導入共享資源
因為我們知道函數(shù)也是對象,所以我們可以把需要共享的方法或?qū)傩苑旁诜旁谒吧砩稀保?
function creatPerson(__name, __sex, __age){ var common = arguments.callee.common; return { // 自身的屬性 name: __name, sex: __sex, age: __age, // 自身的方法 sayhi: function (){alert("hi" );}, // 共享的方法 get: common.get, getType: common.getType, // 共享的屬性 type: common.type }; } creatPerson.common = { get: function (__key){ alert( this [__key]); }, getType: function (){ alert( this .type); }, type: "Person" }; var Bob = creatPerson("Bob", "male", 18 ); Bob.get( "name"); // Bob Bob.get("sex"); // male Bob.getType(); // Person
于是我們就用蹩腳的方法,成功的創(chuàng)建了一個擁有自有屬性方法和共享屬性方法的對象。但實際上,Javascript就是這么蹩腳地創(chuàng)建對象的。
其實共享屬性沒有真正實現(xiàn),因為這個共享屬性,依然只是一個副本。這并不是我們真正希望的共享屬性。
?
new關鍵字
和上面的“對象的構建”相同,new的目的是創(chuàng)建對象的自有屬性和方法。例如:
function Person(__name, __sex, __age){ this .name = __name; this .sex = __sex; this .age = __age; this .get = function (__key){ alert( this [__key]); }; } var Bob = new Person("Bob", "male", 18 ); Bob.get( "name"); // Bob Bob.get("sex"); // male Bob.get("age"); // 18
?
原型(Prototype)
Javascript的作者用了和上面“導入共享資源”的方法差不多。既然函數(shù)也是對象,那么把需要共享的“東東”放在他“身上”吧:
function Person(__name, __sex, __age){ this .name = __name; this .sex = __sex; this .age = __age; this .sayhi = function (__key){ alert( "hi" ); }; } Person.prototype = { constructor: Person, get: function (__key){ alert( this [__key]); } }; var Bob = new Person("Bob", "male", 18 ); Bob.get( "name"); // Bob Bob.get("sex"); // male alert(Bob.constructor); // function Person
Javascript創(chuàng)建對象的模型是簡潔的,new來處理自身問題,prototype來處理共享問題。
如果說Java的對象(實例)產(chǎn)生方式是將原材料丟到模子里(類)熔煉而成;那么Javascript的對象產(chǎn)生方式就是給材料給建筑工(構造函數(shù))讓他按圖紙搭建而成。
?
實際流程
當然實際流程并稍稍有些變化,新建一個對象先做的是處理共享資源,例如:
function A(){ console.dir( this ); alert( this .type); // A } A.prototype.type = "A" ; var a = new A();
通過console.dir將a打印出來我們可以看到:
type "A" __proto__ A {type = "A"} type "A" constructor A() ?
?
?
構造函數(shù)新建一個對象以后,立刻將其prototype的引用賦給新建對象的內(nèi)部屬性__proto__,然后再運行構造函數(shù)里面的構造語句。
?
并沒有覆蓋
function A(){ this .type = "B" } A.prototype.type = "A" ; var a = new A(); alert(a.type); // B
當我們想得到a.type時,引擎會先去在a對象中查看是否有屬性type,如果有則返回該屬性,沒有則試圖在__proto__中查找是否有type屬性,如果有則返回該屬性。
__proto__并不是標準的,比如IE上沒有,但IE上也有類似的內(nèi)部屬性,但我們也無法使用它。
基于這個原因,我們刪掉a.type時依然可以返回a.type:
function A(){ this .type = "B" } A.prototype.type = "A" ; var a = new A(); alert(a.type); // B delete a.type; alert(a.type); // A
?
到底有沒有類?
- 嚴格地講,Javascript并沒有類(class)這種東西。
- 但有時候我們會用構造函數(shù)的名字作為利用該構造函數(shù)創(chuàng)建的對象們的“類型(type not class)名”,以方便我們用Javascript進行面向?qū)ο缶幊虝r的交流。
名字只是一個代號,一個方便理解的工具罷了。
?
?
參考文獻
Javascript繼承機制的設計思想 . 阮一峰?.?2011年6月5日
?
補充閱讀
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
