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

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

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

    duansky'weblog

    統(tǒng)計(jì)

    留言簿(3)

    友情鏈接

    閱讀排行榜

    評(píng)論排行榜

    從 prototype.js 深入學(xué)習(xí) javascript 的面向?qū)ο筇匦?/a>

    prototype.js 深入學(xué)習(xí) javascript 的面向?qū)ο筇匦?/p>

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

    不過(guò)我接觸的動(dòng)態(tài)語(yǔ)言只有: js ruby python flash的as 簡(jiǎn)單的幾門, 應(yīng)該算是井底之蛙之見(jiàn)。

    js 語(yǔ)法成分簡(jiǎn)單,沒(méi)有 ruby 語(yǔ)言復(fù)雜。所以有時(shí)候我覺(jué)得她更干凈(Ruby Fans 不要攻擊我哦,我也是很愛(ài)很愛(ài)很愛(ài)Ruby的)!

    prototype .js 無(wú)疑是 js的漂亮之作,從它身上應(yīng)該可以學(xué)到一些東西。

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

    好了,開(kāi)始吧。

    現(xiàn)在我突然想起了 Thinking in java?中的 "一切皆是對(duì)像", 其實(shí)我覺(jué)得這句話 有點(diǎn)不適合 java 反倒是更適合 js


    1.怎樣構(gòu)造(初始化)對(duì)象?

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

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

    我們也來(lái)試試:

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

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

    看到嗎? sayHello 是一個(gè)方法哦,不要驚慌,"一切都是對(duì)象",所以它和 name 是一樣的,只不過(guò)初始化,或定義的語(yǔ)法不一樣。想起 js 中的正則表達(dá)式中的那兩個(gè)桿桿了嗎? 可愛(ài)吧!

    方法是對(duì)象,所以它可以被當(dāng)作參數(shù)傳遞,或者作為方法的返回值。

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

    沒(méi)問(wèn)題吧,繼續(xù)!

    2. 構(gòu)造函數(shù)?

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

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

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

    所以 var bencode = new Persion("bencode"); 就是構(gòu)造了一個(gè)新的對(duì)象,Person() 相當(dāng)于構(gòu)造函數(shù)

    所以 new 這個(gè)關(guān)鍵字, 就是構(gòu)造一個(gè)新的對(duì)象,并且在這個(gè)對(duì)象上調(diào)用相應(yīng)的方法,并將這個(gè)對(duì)象返回。

    按上面說(shuō): 方法 如果用在 在 new 后面,就相當(dāng)于成了構(gòu)造函數(shù)了。

    話又說(shuō)回來(lái)了, 如果 var bencode = new Persion("bencode") 是 構(gòu)造了一個(gè)對(duì)象,像Java, 那么 Person 是不是類呢?
    可是 Person 不是方法嗎? 可是方法不也是對(duì)象嗎? 類也是對(duì)象?

    一切皆對(duì)象?

    本來(lái)無(wú)一物!

    好了,看 prototype.js吧

    js 代碼
    var?Class?=?{????
    ??create:?
    function()?{????
    ????
    return?function()?{????
    ??????
    this.initialize.apply(this,?arguments);????
    ????}
    ????
    ??}
    ????
    }
    ???

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

    所以如果我們這么做:

    js 代碼
    var?A?=?Class.create();?//?此時(shí)?A?是一個(gè)方法,方法體,下面解釋????
    var?a?=?new?A();??//?對(duì)方法使用?new?操作符,就是構(gòu)造一個(gè)新的對(duì)象,然后在這個(gè)對(duì)象上調(diào)用這個(gè)方法(?現(xiàn)在是?A)?

    上面分析說(shuō)? A相當(dāng)于類, 哈哈 Class.create();??// 終于名副其實(shí)
    var a = new A(...);??// 也是相當(dāng)?shù)刂庇^, 就是構(gòu)造一個(gè)新的對(duì)象,類型 是A

    new 操作符構(gòu)造了對(duì)象,并調(diào)用了 方法, 這個(gè)方法到底做了什么呢? 也就是上面沒(méi)有分析的東東,看看先:

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

    [1]. new 操作符,就會(huì)在新產(chǎn)生的對(duì)象上調(diào)用這個(gè)方法
    [2]. 哦? 這里就是調(diào)用 this 對(duì)象上的 initialize方法, 并傳遞 arguments
    ? 換句話說(shuō),就是把構(gòu)造的任務(wù)委托給 initialize 方法
    ? initialize? 哪里來(lái)? 見(jiàn)下面,類的擴(kuò)展(繼承)
    ?
    3. prototype?

    看段老代碼:

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

    bencode不是一個(gè)自閉的人,他應(yīng)該可以向javaeye介紹一下自己。
    像這樣:

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

    所以。需要給 Person 類加"實(shí)例方法"

    題外話: 靜態(tài)方法如何添加? 看上面的 Class.create, 僅僅是一個(gè)對(duì)象的成員而已

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

    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();???

    運(yùn)行代碼,通過(guò)!

    prototype是啥? 請(qǐng)暫時(shí)忘記 Prototype(prototype.js) 這個(gè)庫(kù),名字一樣而已!

    讓我們?cè)購(gòu)慕Y(jié)果上去分析(第一次我們用這種方法分析而得出了 new 的作用),

    我們?cè)谒伎迹?br />?要想 bencode.sayHello() 正常運(yùn)行
    ?bencode 是一個(gè)對(duì)象, 這是我們已經(jīng)知道的
    ?sayHello() 應(yīng)該是 bencode 這個(gè)對(duì)象的方法才可以
    ?
    ?可是bencode 這個(gè)對(duì)象是 new 操作符產(chǎn)生的, 而 new 此時(shí)作用于 Person 這個(gè) "類"
    ?那么, 哦? 那么有兩種可能:
    ?1. new 產(chǎn)生的那個(gè)新對(duì)象是不是就是 Person.prototype
    ?2. Person.prototype 中的成員 將會(huì)被 new 操作符添加到 新產(chǎn)生的對(duì)象中

    再看:

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

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

    回憶起這段:

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

    如果這里的 this 代表著新產(chǎn)生的對(duì)象的話。
    那么第二種情況就講得通了, new 將會(huì)把 Person.prototype 這個(gè)對(duì)象的成員放到 這個(gè)新對(duì)象中。 與當(dāng)前行為相符。

    所以: Person 的 prototype 對(duì)象中的 成員, 將會(huì)被添加到 新產(chǎn)生的對(duì)象 中(我是這樣理解的)
    (不知道 Js解釋器是不是開(kāi)源的, 有空我得去看看,怎么實(shí)現(xiàn)的。)

    嘿,默認(rèn)的 prototype 就是 Object 哦!

    4. 擴(kuò)展?繼承?

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

    還是實(shí)際點(diǎn):

    有一個(gè)類A, 它有一個(gè) sayHello方法

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

    我想構(gòu)造一個(gè) B 類,讓他繼承 A 對(duì)象, 這句話太抽象。

    其實(shí)我們可能想這樣:

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

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

    怎么辦到呢?

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

    怎么樣添加"實(shí)例方法"?? 快點(diǎn)想起 prototype!!!

    B.prototype = A.prototype

    這樣行了嗎? 恭喜, 運(yùn)行通過(guò)!

    讓我們整合一次

    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");????
    ?}
    ????
    }
    ???

    我們是不是應(yīng)該將 A.prototype 中的內(nèi)容添加到 B.prototype 對(duì)象中,而不是代替它呢? 當(dāng)然。

    這樣才能"擴(kuò)展"

    題外話?多態(tài)在哪里? 嘿嘿

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

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

    這個(gè)只是簡(jiǎn)單地把 source 的成員, 添加到 destination 對(duì)象中嘛, 哪里看得出擴(kuò)展?

    如果我這樣呢?

    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類成員,?如果是同名,則覆蓋,行為符合?"多態(tài)"????
    ?sayHi:?function()?{????
    ??alert(
    "sayHi?B");????
    ?}
    ????
    }
    );??

    回憶剛才的 Class.create():

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

    剛才說(shuō)過(guò), 調(diào)用 new 時(shí), 將會(huì)創(chuàng)建一個(gè)新對(duì)象,并且調(diào)用 Person 方法, Person 方法會(huì)委托給 "新產(chǎn)生對(duì)象"的 initialize方法

    怎么樣給新產(chǎn)生對(duì)象添加 initialize 方法? 哈哈,輕松

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

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

    如果我們要繼承一個(gè)類,只要:

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

    主站蜘蛛池模板: 亚洲人成色99999在线观看| 亚洲精品视频在线免费| 国产伦精品一区二区三区免费下载 | 免费人成网站永久| 日韩免费在线视频| 久草视频免费在线| 亚洲成人黄色网址| 国产精品永久免费视频| 亚洲av中文无码| 亚洲AV成人精品网站在线播放| 国产精品亚洲自在线播放页码| 亚洲黄色免费网站| 亚洲中文字幕日本无线码| 成人免费无毒在线观看网站| 亚洲欧洲国产精品香蕉网| 中文精品人人永久免费 | 亚洲色av性色在线观无码| 成人a毛片视频免费看| 国产国拍亚洲精品福利| 亚洲欧美日韩一区二区三区在线| 热久久精品免费视频| 亚洲av无码偷拍在线观看| 亚洲国产精品自在拍在线播放 | 免费国产成人午夜在线观看| 国产成人免费手机在线观看视频 | 亚洲香蕉免费有线视频| 91在线视频免费91| 亚洲AV无码国产丝袜在线观看| 黄色免费在线网站| 亚洲va在线va天堂成人| 国产一精品一aⅴ一免费| 中文字幕在线视频免费观看| 亚洲自偷自拍另类图片二区| 成人免费无码大片a毛片软件| 一级做a爰片性色毛片免费网站 | 日韩免费观看一区| 亚洲精品无码av片| 18禁无遮挡无码网站免费| 美女免费视频一区二区三区| 亚洲AV成人片色在线观看| 国产三级免费电影|