JAVA EVERY DAY

          DAY DAY UP , STUDY HARD

          常用鏈接

          統計

          積分與排名

          developerWorks Sites

          Java

          JBlog

          OpenSource

          最新評論

          Prototype學習之初始化和繼承

          從 prototype.js 深入學習 javascript 的面向對象特性

          1.怎樣構造(初始化)對象?

          js 代碼
          ?
          1. var ?Prototype?=?{ ??
          2. ??Version:?'1.5.0_rc1', ??
          3. ??ScriptFragment:?'(?:)((\n|\r|.)*?)(?:<\/script>)', ??
          4. ??
          5. ??emptyFunction:? function ()?{}, ??
          6. ??K:? function (x)?{ return ?x} ??
          7. } ??

          就這樣,初始化了一個對象(名字就叫 Prototype),以及對象的四個成員: Version, ScriptFragment, emptyFunction, K

          我們也來試試:

          js 代碼
          ?
          1. var ?bbs?=?{ ??
          2. ?name:?'JavaEye', ??
          3. ?version:?'2.0', ??
          4. ?describe:? "做最棒的軟件開發交流區" , ??
          5. ?sayHello:? function ()?{?alert( "hello,?i'm?javaeye!?" )?} ??
          6. }??

          于是你可以這樣使用: bbs.name 或 bbs.sayHello()

          看到嗎? sayHello 是一個方法哦,不要驚慌,"一切都是對象",所以它和 name 是一樣的,只不過初始化,或定義的語法不一樣。想起 js 中的正則表達式中的那兩個桿桿了嗎? 可愛吧!

          方法是對象,所以它可以被當作參數傳遞,或者作為方法的返回值。

          所以 Prototype 中有一個 Version 屬性,還有一個匹配 script 的正則式字符串, 一個空方法emptyFunction,還有一個方法 K, 它僅僅返回參數。

          沒問題吧,繼續!

          2. 構造函數?

          先讓我們寫段代碼吧(中學時,我語文極差(大學沒語文了),我想寫代碼讓你們明白我心里真實的想法):

          js 代碼
          ?
          1. var ?Person?=? function (name)?{? //?這里?Person?是一個方法 ??
          2. ? this .name?=?name; ??
          3. } ??
          4. var ?bencode?=? new ?Persion( "bencode" );?? //?這里像Java吧! ??
          5. alert(bencode.name);??

          先看結果:
          從 alert(bencode.name); 可以知道,bencode是對象, 而 name 就是 bencode 的屬性, 它被正確地初始化為 "bencode"

          所以 var bencode = new Persion("bencode"); 就是構造了一個新的對象,Person() 相當于構造函數

          所以 new 這個關鍵字, 就是構造一個新的對象,并且在這個對象上調用相應的方法,并將這個對象返回。

          按上面說: 方法 如果用在 在 new 后面,就相當于成了構造函數了。

          話又說回來了, 如果 var bencode = new Persion("bencode") 是 構造了一個對象,像Java, 那么 Person 是不是類呢?
          可是 Person 不是方法嗎? 可是方法不也是對象嗎? 類也是對象?

          一切皆對象?

          本來無一物!

          好了,看 prototype.js吧

          js 代碼
          ?
          1. var ?Class?=?{ ??
          2. ??create:? function ()?{ ??
          3. ???? return ? function ()?{ ??
          4. ?????? this .initialize.apply( this ,?arguments); ??
          5. ????} ??
          6. ??} ??
          7. }??

          初始化一個 Class 對象, 它有一個成員,是一個方法, 這個方法返因另一個方法(方法是對象,所以可以作為參數或者返回值)

          所以如果我們這么做:

          js 代碼
          ?
          1. var ?A?=?Class.create();? //?此時?A?是一個方法,方法體,下面解釋 ??
          2. var ?a?=? new ?A(...);?? //?對方法使用?new?操作符,就是構造一個新的對象,然后在這個對象上調用這個方法(?現在是?A) ??

          上面分析說? A相當于類, 哈哈 Class.create();??// 終于名副其實
          var a = new A(...);??// 也是相當地直觀, 就是構造一個新的對象,類型 是A

          new 操作符構造了對象,并調用了 方法, 這個方法到底做了什么呢? 也就是上面沒有分析的東東,看看先:

          js 代碼
          ?
          1. var ?Class?=?{ ??
          2. ??create:? function ()?{ ??
          3. ???? return ? function ()?{?? //?見[1] ??
          4. ?????? this .initialize.apply( this ,?arguments);?? //?見[2] ??
          5. ????} ??
          6. ??}? ??
          7. }??

          [1]. new 操作符,就會在新產生的對象上調用這個方法
          [2]. 哦? 這里就是調用 this 對象上的 initialize方法, 并傳遞 arguments
          ? 換句話說,就是把構造的任務委托給 initialize 方法
          ? initialize? 哪里來? 見下面,類的擴展(繼承)
          ?
          3. prototype?

          看段老代碼:

          js 代碼
          ?
          1. var ?Person?=? function (name)?{ ??
          2. ? this .name?=?name; ??
          3. } ??
          4. var ?bencode?=? new ?Person( "bencode" );??

          bencode不是一個自閉的人,他應該可以向javaeye介紹一下自己。
          像這樣:

          js 代碼
          1. bencode.sayHello();???


          ?
          假如不能實現以上功能的話, 上面的 new,上面所有的東東都等于垃圾。

          所以。需要給 Person 類加"實例方法"

          題外話: 靜態方法如何添加? 看上面的 Class.create, 僅僅是一個對象的成員而已

          好, 再來一段 (為了完整性,上面的幾句話,再抄一次)

          js 代碼
          ?
          1. var ?Person?=? function (name)?{ ??
          2. ? this .name?=?name; ??
          3. } ??
          4. Person.prototype?=?{?? //?protype?是啥? ??
          5. ?sayHello:? function ()?{ ??
          6. ??alert( "hi,?javaeye,?I'm?" ?+? this .name); ??
          7. ?} ??
          8. } ??
          9. var ?bencode?=? new ?Person( "bencode" ); ??
          10. bencode.sayHello();??

          運行代碼,通過!

          prototype是啥? 請暫時忘記 Prototype(prototype.js) 這個庫,名字一樣而已!

          讓我們再從結果上去分析(第一次我們用這種方法分析而得出了 new 的作用),

          我們在思考:
          ?要想 bencode.sayHello() 正常運行
          ?bencode 是一個對象, 這是我們已經知道的
          ?sayHello() 應該是 bencode 這個對象的方法才可以
          ?
          ?可是bencode 這個對象是 new 操作符產生的, 而 new 此時作用于 Person 這個 "類"
          ?那么, 哦? 那么有兩種可能:
          ?1. new 產生的那個新對象是不是就是 Person.prototype
          ?2. Person.prototype 中的成員 將會被 new 操作符添加到 新產生的對象中

          再看:

          js 代碼
          ?
          1. Person.prototype?=?{ ??
          2. ?sayHello:? function ()?{ ??
          3. ??alert( "hi,?javaeye,?I'm?" ?+? this .name);? //?這里有this ??
          4. ?} ??
          5. }??

          this.name, 這里的 this 指什么?所以第一個可能講不通呀

          回憶起這段:

          js 代碼
          ?
          1. var ?Person?=? function (name)?{ ??
          2. ? this .name?=?name; ??
          3. }??

          如果這里的 this 代表著新產生的對象的話。
          那么第二種情況就講得通了, new 將會把 Person.prototype 這個對象的成員放到 這個新對象中。 與當前行為相符。

          所以: Person 的 prototype 對象中的 成員, 將會被添加到 新產生的對象 中(我是這樣理解的)
          (不知道 Js解釋器是不是開源的, 有空我得去看看,怎么實現的。)

          嘿,默認的 prototype 就是 Object 哦!

          4. 擴展?繼承?

          什么是擴展?啥是繼承? ! 我從爸爸那得到了什么?
          想不通!

          還是實際點:

          有一個類A, 它有一個 sayHello方法

          js 代碼
          ?
          1. var ?A?=? function ()?{ ??
          2. } ??
          3. ??
          4. A.prototype?=?{ ??
          5. ?sayHello:? function ()?{ ??
          6. ??alert( "sayHello?A" ) ??
          7. ?} ??
          8. } ??

          我想構造一個 B 類,讓他繼承 A 對象, 這句話太抽象。

          其實我們可能想這樣:

          js 代碼
          ?
          1. var ?b?=? new ?B(); ??
          2. b.sayHello();?? //?調用?A?的?sayHello ??

          這應該是繼承的第一層含義(重用)

          怎么辦到呢?

          var B = function() {?// 這里是有一個B類了
          }

          怎么樣添加"實例方法"?? 快點想起 prototype!!!

          B.prototype = A.prototype

          這樣行了嗎? 恭喜, 運行通過!

          讓我們整合一次

          js 代碼
          ?
          1. var ?A?=? function ()?{ ??
          2. } ??
          3. A.prototype?=?{ ??
          4. ?sayHello:? function ()?{ ??
          5. ??alert( "sayHello?A" ); ??
          6. ?} ??
          7. } ??
          8. ??
          9. var ?B?=? function ()?{ ??
          10. } ??
          11. B.prototype?=?A.prototype; ??
          12. ??
          13. var ?b?=? new ?B(); ??
          14. b.sayHello();? ??

          可是如果 B 是這樣呢?

          js 代碼
          ?
          1. var ?B?=? function ()?{ ??
          2. } ??
          3. B.prototype?=?{ ??
          4. ?sayHi:? function ()?{ ??
          5. ??alert( "sayHi?B" ); ??
          6. ?} ??
          7. }??

          我們是不是應該將 A.prototype 中的內容添加到 B.prototype 對象中,而不是代替它呢? 當然。

          這樣才能"擴展"

          題外話?多態在哪里? 嘿嘿

          好了,足夠多了, 那prototype.js 是怎么樣"擴展"的呢?

          js 代碼
          ?
          1. Object.extend?=? function (destination,?source)?{ ??
          2. ?? for ?( var ?property? in ?source)?{ ??
          3. ????destination[property]?=?source[property]; ??
          4. ??} ??
          5. ?? return ?destination; ??
          6. }??

          這個只是簡單地把 source 的成員, 添加到 destination 對象中嘛, 哪里看得出擴展?

          如果我這樣呢?

          js 代碼
          ?
          1. var ?A?=? function ()?{ ??
          2. } ??
          3. A.prototype?=?{ ??
          4. ?sayHello:? function ()?{ ??
          5. ??alert( "sayHello?A" ) ??
          6. ?} ??
          7. } ??
          8. ??
          9. var ?B?=? function ()?{ ??
          10. } ??
          11. Object.extend(B.prototype,?A.prototype);? //?先添加父類(A)成員 ??
          12. Object.extend(B.prototype,?{? //?再添加B類成員,?如果是同名,則覆蓋,行為符合?"多態" ??
          13. ?sayHi:? function ()?{ ??
          14. ??alert( "sayHi?B" ); ??
          15. ?} ??
          16. }); ??

          回憶剛才的 Class.create():

          js 代碼
          ?
          1. var ?Person?=?Class.create(); ??
          2. var ?bencode?=? new ?Person( "bencode" );??

          剛才說過, 調用 new 時, 將會創建一個新對象,并且調用 Person 方法, Person 方法會委托給 "新產生對象"的 initialize方法

          怎么樣給新產生對象添加 initialize 方法? 哈哈,輕松

          js 代碼
          ?
          1. Object.extend(Person.prototype,?{ ??
          2. ?initialize:? function ()?{ ??
          3. ?? this .name?=?name; ??
          4. ?}? //, ??
          5. ? //?下面可以添加其他實例方法。 ??
          6. });??


          所以, 我們使用 prototype 創建類一般格式是這樣的:

          js 代碼
          ?
          1. var ?ClassName?=?Class.create(); ??
          2. Object.extend(ClassName.prototype,?{ ??
          3. ?initialize:? function (...)?{? //?這就相當于構造函數 ??
          4. ?} ??
          5. ? //... ??
          6. });??

          如果我們要繼承一個類,只要:

          js 代碼
          ?
          1. var ?ClassName?=?Class.create(); ??
          2. Object.extend(ClassName.prototype,?SuperClassName.prototype); ??
          3. Object.extend(ClassName.prototype,?{ ??
          4. ?initialize:? function (...)?{ ??
          5. ?} ??
          6. ? //... ??
          7. });??

          面向對象部分基本上就這樣。

          posted on 2007-03-20 13:20 沒有魚的水 閱讀(566) 評論(1)  編輯  收藏 所屬分類: AJAX

          評論

          # re: Prototype學習之初始化和繼承 2008-10-07 15:11 hq

          多謝  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 阆中市| 镇宁| 宁陕县| 汉源县| 彰化县| 嘉义市| 铅山县| 桑日县| 伊金霍洛旗| 敦煌市| 大安市| 郸城县| 吉首市| 门源| 科尔| 宝坻区| 张家口市| 昭通市| 治县。| 河池市| 唐河县| 淅川县| 焉耆| 新巴尔虎左旗| 福鼎市| 农安县| 册亨县| 商水县| 达拉特旗| 姚安县| 阜新| 永新县| 文山县| 响水县| 海丰县| 彰化县| 石林| 富阳市| 南昌市| 梅州市| 平武县|