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

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

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

    JAVA & XML & JAVASCRIPT & AJAX & CSS

    Web 2.0 技術(shù)儲(chǔ)備............

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      77 隨筆 :: 17 文章 :: 116 評(píng)論 :: 0 Trackbacks
    作者:liuruhong

    Javascript對(duì)于做過(guò)Web程序的人不應(yīng)該是陌生,初期是用來(lái)做一些簡(jiǎn)單的FORM驗(yàn)證,基本上是在玩弄一些技巧性的東西。IE 4.0引入了DHTML,同時(shí)為了對(duì)抗Netscape的Javascript,提出了自己的腳本語(yǔ)言JScript,除了遵循EMAC的標(biāo)準(zhǔn)之外,同時(shí)增加了許多擴(kuò)展,如下要提到的OOP編程就是其中的一個(gè),為了命且概念,我以下提到的Javascript都是Microsoft Internet Explorer 4.0以上實(shí)現(xiàn)的JScript,對(duì)于Netscape,我沒(méi)有做過(guò)太多的程序,所以一些的區(qū)別也就看出來(lái)。


    Javascript不是一個(gè)支持面向?qū)ο蟮恼Z(yǔ)言,更加算不上一個(gè)開(kāi)發(fā)平臺(tái),但是Javascript提供了一個(gè)非常強(qiáng)大的基于prototype的面向?qū)ο笳{(diào)用功能,你可以在你自己需要的地方使用他們。因此,如何使用對(duì)象?本文盡可能從Javascript面向?qū)ο髮?shí)現(xiàn)原理出發(fā),解析清楚它的工作模型。在了解這些模型之后,你可以在自己的腳本庫(kù)中編寫(xiě)一些實(shí)現(xiàn)代碼,然后在其他地方調(diào)用。



    Javascript的語(yǔ)法和C++很接近,不過(guò)在類(lèi)實(shí)現(xiàn)中沒(méi)有使用關(guān)鍵字Class,實(shí)現(xiàn)繼承的時(shí)候也沒(méi)有采用傳統(tǒng)的Public或者Implement等等所謂的關(guān)鍵字來(lái)標(biāo)示類(lèi)的實(shí)現(xiàn)。這樣的情況下,可能有就有人會(huì)問(wèn),如何編寫(xiě)Javascript的Class,如何實(shí)現(xiàn)繼承。我開(kāi)始也是百思不得其解,后來(lái)看了MSDN,才知道采用了prototype來(lái)實(shí)現(xiàn),包括繼承和重載,也可以通過(guò)這個(gè)關(guān)鍵字來(lái)實(shí)現(xiàn)。



    Javascript的函數(shù)很奇怪,每個(gè)都是默認(rèn)實(shí)現(xiàn)了Optional的,即參數(shù)都可以可選的,function a(var1,var2,var3),在調(diào)用的過(guò)程中a(),a(value1),a(value1,value2)等等的調(diào)用都是正確的,至少在即使編譯部分可以完整通過(guò),至于其它,只是和函數(shù)的實(shí)現(xiàn)邏輯比較相關(guān)了。

    以下就JS對(duì)于類(lèi)的實(shí)現(xiàn)、繼承、重載詳細(xì)介紹其實(shí)現(xiàn)方式。

    1。實(shí)現(xiàn)

    Js類(lèi)的實(shí)現(xiàn)就通過(guò)函數(shù)直接實(shí)現(xiàn)的,每個(gè)函數(shù)可以直接看成class,如下代碼

    function ClassTest1(){

    ...//implement code

    }

    var a=new ClassTest1



    function ClassTest2(var1){

    ...//implement code

    }

    var b=new ClassTest("value")

    對(duì)于類(lèi)的屬性,可以通過(guò)兩種方式實(shí)現(xiàn)

    1)this."<Property or Method"的方式實(shí)現(xiàn),在類(lèi)聲明函數(shù)中直接給出函數(shù)的實(shí)現(xiàn),如 this.Add=new function(strUserName,strPassword)這樣的方式調(diào)用,編寫(xiě)的方式在Class Function中調(diào)用。

    2)通過(guò)ClassFunction.prototype.[FunctionName]=function(var1,var2...){//todo}這樣的方式完成調(diào)用。

    這兩種方式從目標(biāo)來(lái)看是一致的,按照我個(gè)人的觀點(diǎn)來(lái)看,區(qū)別的只是在于實(shí)現(xiàn)方式,通過(guò)this.propertyName的方式來(lái)創(chuàng)建,Jscript自動(dòng)創(chuàng)建了property或者method的入口,不過(guò)從程序的角度而言,還是使用prototype的關(guān)鍵字實(shí)現(xiàn)比較靈活。



    另外Javascript也可以和我們C++中那種嵌套聲明的方法來(lái)聲明,C++實(shí)現(xiàn)的方法如下

    Public Class ClassName:ParentClass{

    Public DataType FunctionName(){



    }

    Public Class ClassName{

    Public DataType FunctionName(){

    }

    }

    }

    在Javascript當(dāng)中,當(dāng)然不存在class這樣的關(guān)鍵字了,所以實(shí)現(xiàn)起來(lái)有點(diǎn)戲劇性,不過(guò)仍然為一個(gè)非常巧妙的實(shí)現(xiàn)。

    function className(){

    //Property Implement

    this.UserName="blue";

    //Method Implement

    this.Add=new function(){



    }

    //Sub Class Implement

    function SubClassName(){

    this.PropertyName="hi"

    }

    //sub class method implement

    SubClassName.prototype.Change=function{



    }

    }

    //Main Class Method Implement

    className.prototype.Delete=function(){



    }

    如上的代碼大致演示了Javascript類(lèi)中屬性和方法的實(shí)現(xiàn),另外有一點(diǎn)比較困惑,整個(gè)class中都是public的,沒(méi)有關(guān)鍵字private之類(lèi)的可以控制某些方法是否隱藏,那么在我們編寫(xiě)代碼實(shí)現(xiàn)的規(guī)范中,我看國(guó)外一些程序員都是使用_functionName這樣子為函數(shù)命的方法來(lái)區(qū)分,但是在調(diào)用過(guò)程中實(shí)際還可以調(diào)用的。

    實(shí)現(xiàn)了屬性和方法,剩下的就是Event的實(shí)現(xiàn)了,我查找了許多資料,包括整個(gè)MSDN關(guān)于JScript的參考,都沒(méi)有看到一個(gè)很好的模型關(guān)于事件實(shí)現(xiàn)的,后來(lái)參考了一些站點(diǎn)編寫(xiě)HTA(HTML Component,有空我會(huì)寫(xiě)一些相關(guān)的文章)的實(shí)現(xiàn),借助于比較扭曲(我個(gè)人認(rèn)為)的方法可以大致的實(shí)現(xiàn)基于事件驅(qū)動(dòng)的功能。大致的思路是這樣子的:

    1).將所有的事件定義成屬性,只要簡(jiǎn)單的聲明就可以

    2).在需要觸發(fā)事件的代碼中判斷事件屬性是否是一個(gè)函數(shù),如果是函數(shù),直接執(zhí)行函數(shù)代碼,如果是字符串,那么執(zhí)行字符串函數(shù),通過(guò)eval(str)來(lái)執(zhí)行。

    3) .在類(lèi)的實(shí)例當(dāng)中注冊(cè)事件函數(shù)。

    為了簡(jiǎn)單說(shuō)明如上的思路,采用timer這樣簡(jiǎn)單的例子來(lái)表述如上的所提到的內(nèi)容,如果只是為了簡(jiǎn)單的實(shí)現(xiàn)timer的功能,Javascript中setInterval函數(shù)就可以滿(mǎn)足全部的要求,如下的代碼只是用來(lái)說(shuō)明Timer的工作原理。

    //Class For Timer
    function Timer(iInterval){
    //if not set the timer interval ,then defalut set to 500ms
    this.Interval=iInterval || 500;
    this._handleInterval;
    this.TimerEvent=null
    function Start(){
    if(this.Interval!=0){
    this._handleInterval=setInterval("TimerCallBack()",this.Interval);
    }
    }
    function Start(){
    clearInterval(this._handleInterval);
    }
    function TimerCallBack(){
    if (typeof this.TimerEvent=="function"){
    this.TimerEvent();
    }
    else if(this.TimerEvent!=null && this.TimerEvent.length>0){
    eval(this.TimerEvent);
    }
    }
    }
    //Code for Instance
    var t=new Timer(3);

    //------------------------------------//

    //1.
    t.TimerEvent=function(){
    //todo
    }

    //2.
    t.TimerEvent="alert(\"hello\")";

    //3.

    t.TimerEvent=tTimerCall;

    //----------------------------------//
    t.Start();
    t.Stop();

    function tTimerCall(){



    }



    實(shí)際工作代碼是在TimerCallBack()上面實(shí)現(xiàn),事件觸發(fā)作為屬性的方式來(lái)實(shí)現(xiàn),在應(yīng)用實(shí)例中,代碼提供了三種方法去調(diào)用事件,不過(guò)在事件的回調(diào)當(dāng)中,我還沒(méi)有想到如何可以帶參數(shù),只有才各自的實(shí)現(xiàn)當(dāng)中訪問(wèn)各自需要的屬性才能夠?qū)崿F(xiàn)全部的要求。



    2。繼承。

    剛采用了大篇幅的文字去介紹如何實(shí)現(xiàn)Javascript的各種實(shí)現(xiàn),也就是從邏輯上完成了一個(gè)封裝class的實(shí)現(xiàn),從某種意義上來(lái)說(shuō),class的實(shí)現(xiàn)是真正腳本編程中使用最多的部分,不過(guò)如果只是要完成如上的功能,使用VBScript來(lái)編寫(xiě)更能更加清晰,畢竟VBscript提供了class關(guān)鍵字,同時(shí)提供了public 和private這兩個(gè)關(guān)鍵字,可以清晰的將公共和私有對(duì)象分離,至于事件的實(shí)現(xiàn),也可以采用類(lèi)似Javascript實(shí)現(xiàn)的思路,只是對(duì)于函數(shù)的引用需要采用GetRef這個(gè)函數(shù),具體的用法可以參考scripting reference,MSDN里頭也有詳細(xì)的介紹,而Javascript強(qiáng)大至于在于如下要說(shuō)的了,雖然具體的東西可能不多。

    如上所言,我們已經(jīng)完成了一個(gè)基本的類(lèi)實(shí)現(xiàn)Timer,現(xiàn)在要做的是重新編寫(xiě)這個(gè)類(lèi),我們簡(jiǎn)單的只是想在這個(gè)類(lèi)之中加入一個(gè)方法,提供當(dāng)前的系統(tǒng)時(shí)間,方法的名稱(chēng)為getSystemDate,顯然如果全部重新編寫(xiě),那就失去了我這里說(shuō)的意義了。先看看如下的實(shí)現(xiàn)。

    function NewTimer(iInterval){

    //call super

    this.base=Timer;

    this.base(iInterval);

    }

    NewTimer.prototype=new Timer;

    NewTimer.prototype.getSystemDate=function(){

    var dt=new Date();

    return dt.getYear()+"-"+dt.getMonth()+"-"+dt.getDay();

    }



    上述代碼實(shí)現(xiàn)了NewTimer類(lèi),從Timer繼承,Javascript沒(méi)有使用“:”或者java的public那樣類(lèi)似的關(guān)鍵字,只是通過(guò)newclassname.prototype=new baseclass這樣的方法來(lái)完成,同時(shí)NewTimer實(shí)現(xiàn)了getSystemDate的方法,在NewTimer的初始化函數(shù)中,我使用了this.base=Timer,是為了引用父類(lèi)的實(shí)現(xiàn),不過(guò)在對(duì)于父類(lèi)其他實(shí)現(xiàn)函數(shù)的調(diào)用,到現(xiàn)在我沒(méi)有找到一個(gè)確定的方法,是否通過(guò)this.base.start()那樣來(lái)調(diào)用還是其他的,如果有誰(shuí)比較清楚的,麻煩告訴我,另外在netscape的站點(diǎn)上,我查到有一個(gè)特殊的"__proto__"的屬性好像是對(duì)于父類(lèi)的直接引用,不過(guò)具體的我也沒(méi)有嘗試過(guò),在msdn中也沒(méi)有看到對(duì)于__proto__的支持。



    3。重載

    或許這個(gè)是OOP編程中比較復(fù)雜的地方了,在Javascript的實(shí)現(xiàn)中有點(diǎn)無(wú)奈,也就是通過(guò)prototype的方式來(lái)完成的,不過(guò)因?yàn)槲也磺宄绾握{(diào)用父類(lèi)的實(shí)現(xiàn)函數(shù),那么在重載中只能夠重新編寫(xiě)所有的實(shí)現(xiàn)了,另外就是在實(shí)現(xiàn)中實(shí)例化一個(gè)父類(lèi),然后通過(guò)調(diào)用它來(lái)返回需要的東西。

    Javascript中所有的對(duì)象都是從Object繼承下來(lái)的,object提供了toString()的方法,也就是說(shuō)如果調(diào)用alert(objInstance)這樣的過(guò)程,實(shí)際上是調(diào)用了alert(objInstance.toString())的方法,如果沒(méi)有編寫(xiě)實(shí)現(xiàn),object默認(rèn)的toString()都是"object object"這樣子的,在許多地方需要重載這個(gè)函數(shù)的,比如Timer,如果我們希望var ins=new Timer(5);alert(ins)調(diào)用得到的是interval的值5,那么就需要重新編寫(xiě)toString()方法了

    Timer.prototype.toString=function(){ return this.Interval};

    以上代碼實(shí)現(xiàn)之后alert(ins)得到的就是5了。



    長(zhǎng)篇累牘的說(shuō)了一堆廢話,終于說(shuō)玩了大致的想法,其實(shí)語(yǔ)言只是一個(gè)實(shí)現(xiàn)工具,重要的在于設(shè)計(jì)的思想,不妨可以考慮一下,在BITI內(nèi)部開(kāi)發(fā)一個(gè)OpenSource的Project,如果是基于javascript的模型來(lái)建立開(kāi)發(fā)平臺(tái)庫(kù),我希望有人可以參與。通過(guò)javascript建立一系列基于Web UI的控件,目前我在開(kāi)發(fā)過(guò)程中也是立足于上述的想法。另外,附上我去年寫(xiě)的類(lèi)似HotMail的按鈕那樣的class源程序,暫時(shí)還沒(méi)有使用Image Preload,希望有人可以幫我修改一下,如果需要可以運(yùn)行的版本,給我發(fā)送Email:liuruhong@263.net。另外有空我會(huì)寫(xiě)基于Javascript的組件編程和多媒體編程部分,再下來(lái)就是XML方面了,希望大家共同進(jìn)步。
    posted on 2006-03-16 18:01 Web 2.0 技術(shù)資源 閱讀(191) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Javascript
    主站蜘蛛池模板: 亚洲性日韩精品一区二区三区 | 亚洲AV无码乱码麻豆精品国产| 国产一级一片免费播放i| 日韩内射激情视频在线播放免费 | 久久电影网午夜鲁丝片免费| 国内精品免费在线观看| 日本高清免费中文在线看| 亚洲av产在线精品亚洲第一站| 亚洲av无码潮喷在线观看| 亚洲视频在线精品| 免费亚洲视频在线观看| 午夜小视频免费观看| 成人免费一级毛片在线播放视频| 成人A片产无码免费视频在线观看| 日韩久久无码免费毛片软件| 亚洲va中文字幕| 亚洲国产精品免费观看 | 久久精品成人免费看| 一级毛片免费全部播放| 大桥未久亚洲无av码在线| 亚洲午夜一区二区三区| 亚洲人成电影在线观看青青| 亚洲色偷偷偷网站色偷一区| 亚洲第一区香蕉_国产a| 亚洲AV人无码综合在线观看| 国产成人无码综合亚洲日韩| 亚洲人成无码网站| 亚洲国产精品久久久天堂| 亚洲人成亚洲人成在线观看| 亚洲精品国产精品乱码在线观看| 中文字幕亚洲一区| 亚洲一区二区三区影院| 亚洲色欲久久久综合网东京热| 毛茸茸bbw亚洲人| 亚洲日本一区二区三区在线| 亚洲级αV无码毛片久久精品| 亚洲精品无码久久久久去q| 国产亚洲精品国产| 亚洲国产精品不卡在线电影| 亚洲欧洲在线观看| 亚洲乱码一二三四五六区|