<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    duansky'weblog

    統計

    留言簿(3)

    友情鏈接

    閱讀排行榜

    評論排行榜

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

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

    js是一門很強大的語言,靈活,方便。 目前我接觸到的語言當中,從語法角度上講,只有 Ruby 比它更爽。

    不過我接觸的動態語言只有: js ruby python flash的as 簡單的幾門, 應該算是井底之蛙之見。

    js 語法成分簡單,沒有 ruby 語言復雜。所以有時候我覺得她更干凈(Ruby Fans 不要攻擊我哦,我也是很愛很愛很愛Ruby的)!

    prototype .js 無疑是 js的漂亮之作,從它身上應該可以學到一些東西。

    如果你用 js 在頁面僅僅能寫出 if, alert等簡單的驗證代碼,或者想多了解一下Js, 那么此文可能對你有幫助。

    好了,開始吧。

    現在我突然想起了 Thinking in java?中的 "一切皆是對像", 其實我覺得這句話 有點不適合 java 反倒是更適合 js


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

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

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

    我們也來試試:

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

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

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

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

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

    沒問題吧,繼續!

    2. 構造函數?

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

    js 代碼
    var?Person?=?function(name)?{?//?這里?Person?是一個方法????
    ?this.name?=?name;????
    }
    ????
    var?bencode?=?new?Persion("bencode");??//?這里像Java吧!????
    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 代碼
    var?Class?=?{????
    ??create:?
    function()?{????
    ????
    return?function()?{????
    ??????
    this.initialize.apply(this,?arguments);????
    ????}
    ????
    ??}
    ????
    }
    ???

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

    所以如果我們這么做:

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

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

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

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

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

    看段老代碼:

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

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

    js 代碼
    bencode.sayHello();????
    假如不能實現以上功能的話, 上面的 new,上面所有的東東都等于垃圾。

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

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

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

    js 代碼
    var?Person?=?function(name)?{????
    ?
    this.name?=?name;????
    }
    ????
    Person.prototype?
    =?{??//?protype?是啥?????
    ?sayHello:?function()?{????
    ??alert(
    "hi,?javaeye,?I'm?"?+?this.name);????
    ?}
    ????
    }
    ????
    var?bencode?=?new?Person("bencode");????
    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 代碼
    Person.prototype?=?{????
    ?sayHello:?
    function()?{????
    ??alert(
    "hi,?javaeye,?I'm?"?+?this.name);?//?這里有this????
    ?}
    ????
    }
    ???

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

    回憶起這段:

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

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

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

    嘿,默認的 prototype 就是 Object 哦!

    4. 擴展?繼承?

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

    還是實際點:

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

    js 代碼
    var?A?=?function()?{????
    }
    ????
    ???
    A.prototype?
    =?{????
    ?sayHello:?
    function()?{????
    ??alert(
    "sayHello?A")????
    ?}
    ????
    }
    ??

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

    其實我們可能想這樣:

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

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

    怎么辦到呢?

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

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

    B.prototype = A.prototype

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

    讓我們整合一次

    js 代碼
    var?A?=?function()?{????
    }
    ????
    A.prototype?
    =?{????
    ?sayHello:?
    function()?{????
    ??alert(
    "sayHello?A");????
    ?}
    ????
    }
    ????
    ???
    var?B?=?function()?{????
    }
    ????
    B.prototype?
    =?A.prototype;????
    ???
    var?b?=?new?B();????
    b.sayHello();?

    可是如果 B 是這樣呢?

    js 代碼
    var?B?=?function()?{????
    }
    ????
    B.prototype?
    =?{????
    ?sayHi:?
    function()?{????
    ??alert(
    "sayHi?B");????
    ?}
    ????
    }
    ???

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

    這樣才能"擴展"

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

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

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

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

    如果我這樣呢?

    js 代碼
    var?A?=?function()?{????
    }
    ????
    A.prototype?
    =?{????
    ?sayHello:?
    function()?{????
    ??alert(
    "sayHello?A")????
    ?}
    ????
    }
    ????
    ???
    var?B?=?function()?{????
    }
    ????
    Object.extend(B.prototype,?A.prototype);?
    //?先添加父類(A)成員????
    Object.extend(B.prototype,?{?//?再添加B類成員,?如果是同名,則覆蓋,行為符合?"多態"????
    ?sayHi:?function()?{????
    ??alert(
    "sayHi?B");????
    ?}
    ????
    }
    );??

    回憶剛才的 Class.create():

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

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

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

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

    所以, 我們使用 prototype 創建類一般格式是這樣的:
    js 代碼
    var?ClassName?=?Class.create();????
    Object.extend(ClassName.prototype,?
    {????
    ?initialize:?
    function()?{?//?這就相當于構造函數????
    ?}
    ????
    ?
    //????
    }
    );

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

    js 代碼
    var?ClassName?=?Class.create();????
    Object.extend(ClassName.prototype,?SuperClassName.prototype);????
    Object.extend(ClassName.prototype,?
    {????
    ?initialize:?
    function()?{????
    ?}
    ????
    ?
    //????
    }
    );??

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

    希望對大家有點幫助!

    本來想再接著寫 prototype.js 的源碼解讀,但一來是因為時間,第二是發現也沒有這個必要。
    這種東西是看起來快,寫起來慢的。哈哈!

    轉自:http://www.javaeye.com/topic/57760

    posted on 2008-08-26 18:21 duansky 閱讀(380) 評論(0)  編輯  收藏 所屬分類: JavaScript

    主站蜘蛛池模板: 精品亚洲视频在线| 亚洲一区二区无码偷拍| 国产成人1024精品免费| 亚洲精品国产福利一二区| 免费高清A级毛片在线播放| 又粗又黄又猛又爽大片免费| 精品亚洲av无码一区二区柚蜜| 午夜时刻免费入口| 国产亚洲蜜芽精品久久| 免费少妇a级毛片人成网| 一级毛片免费播放男男| 亚洲综合无码AV一区二区| 精品国产麻豆免费人成网站| 亚洲国产精品嫩草影院在线观看| 无码日韩精品一区二区三区免费 | 亚洲国产美女精品久久久久| 久久精品国产免费观看三人同眠| 亚洲乱人伦精品图片| 欧美男同gv免费网站观看| WWW亚洲色大成网络.COM| 亚洲人成人网站在线观看| 在线看片免费人成视频久网下载| 久久国产精品亚洲一区二区| 亚洲免费视频观看| 亚洲日韩久久综合中文字幕| 免费人成无码大片在线观看| a级毛片在线免费看| 亚洲大片免费观看| 啊v在线免费观看| 免费污视频在线观看| 亚洲中文字幕一二三四区| 亚洲国产一区明星换脸| 久久国产乱子伦免费精品| 亚洲国产精品18久久久久久| 久久亚洲中文字幕精品一区四| 免费精品99久久国产综合精品| 国产99在线|亚洲| 久久亚洲国产成人影院网站 | 亚洲人成网亚洲欧洲无码| 久久国产成人精品国产成人亚洲| 秋霞人成在线观看免费视频|