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

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

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

    posts - 0, comments - 77, trackbacks - 0, articles - 356
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    javascript 的面向對象特性參考

    Posted on 2008-01-15 15:49 semovy 閱讀(475) 評論(0)  編輯  收藏 所屬分類: JavaScript

    最近在看用javascript+css實現(xiàn)rich client。javascript 也是一個蠻有意思的語言。特別是其面向對象的實現(xiàn)和其他“標準”的OO launguage有很大的不同。但是,都是動態(tài)語言,我還是覺得它比起python語法和庫都差得太遠。可是沒有explorer支持python開發(fā) 啊。。。:(

    這是我學習javascript中面向對象特性的一點總結。希望對具有其他語言的面向對象設計經(jīng)驗的朋友理解javascript的OO有所幫助。我具有c++,java和python的面向對象設計的經(jīng)驗。

    總的感受, javascript作為一種弱類型的動態(tài)語言,語法接近于java,但其面向對象的方式更和python相識。

    1 面向對象的特性

    類,成員變量,成員函數(shù),類變量,類方法,繼承,多態(tài)

    1) 類

    類的定義:function Circle(r) { this.r = r; }

    類的實例化: c = Circle(3);

    2)成員變量

    成員變量在初始化函數(shù)里申明:this.r = r;

    注意,在對象生成后,你也可以給它附上成員變量,比如c.name="my circle",

    但是除非特別的需要,我強烈建議你不要這樣做。也就是所有的成員都應在初始化函數(shù)里聲明。我認為這是一種好的style。

    這一點和python很相識。

    3)成員函數(shù)

    成員函數(shù)的標準形式是這樣的:

    Cricle.prototype.area = function() { return 3.14 * this.r * this.r; }

    這和java或python或c++都大不一樣。但為了幫助理解,你可以把prototype看作基類。

    prototype里面的變量或方法,是所有對象共享的。

    比如,c.area()調用最終就會讓解釋器調用到Circle.prototype.area().

    相比于java和c++,javascript具有他們都沒有的一個語義,也就是你可以在prototype里定義變量。定義在prototype里的變量可以被所有的實例共享量。所以一般它應該是一個常數(shù),比如:Circle.prototype.PI = 3.14.

    顯然,prototype里的變量和方法都應該是不變的。每一個對象實例都不應該取修改prototype中的內容。雖然語言允許你可以這樣做,但這樣做沒有任何意義,也違反了面向對象的語義(想想,java會讓你動態(tài)修改一個類的方法嗎)。

    當然,對于多態(tài)是另外一回事,在后面詳述。

    而且,我建議所有的成員函數(shù)都在緊接類定義的地方定義。而不應該在代碼運行的某個地方對一個對象實例增加/修改成員函數(shù)。這樣的結果是javascript的類定義盡量向java看齊。使得代碼更清晰。

    4)類變量

    類變量是屬于一個類的變量。就像java里用static修飾的變量。因為它屬于類,所以它也應該是一個常量。實例不應該去修改它,雖然你可以 (java里可以用final修飾,使得類變量一旦定義,就不能修改)。這里可以看到,類變量和prototype里定義的變量的功能是相似的。確實如 此,他們的目的都是一樣的。但他們的訪問方式

    不一樣。比如:

    Circle.prototype.PI = 3.14;

    Circle.PI = 3.14;

    //用prototype里的變量

    Circle.prototype.area1 = function() { return this.PI * this.r * this.r; }

    //用類變量

    Circle.prototype.area2 = function() { return Circle.PI * this.r * this.r; }

    5)類方法

    這個概念應該很簡單。注意類方法里絕對不要用this關鍵字,和java完全一樣。

    Circle.max = function(a, b) {
        return a.r > b.r ? a : b;
    }

    theMax = Circle(new Circle(1), new Circle(4));

    6)繼承

    子類繼承父類,那么 “子類實例” 具有和 “父類實例” 完全一樣的行為。javascript是這樣實現(xiàn)的。

    function SubCircle(x, y, r) {
      this.x = x;
      this.y = y;
      this.r =r;
    }

    SubCircle.prototype = new Circle(0);
    記得前面說的嗎?可以把prototype看作一個基類。這里,prototype確確實實是一個基類。它是如何實現(xiàn)的呢?

    舉例如下:
    sc = SubCirlce(1,1,3);
    sc.area();

    調用的傳遞:
    sc.area()->sc.prototype.area()->Circle(0).area()->Circle.prototype.area().
    看來是不是很奇妙呢。

    通過這種方式,javascript實現(xiàn)了繼承。

    7)多態(tài)

    多態(tài)是子類會定義和父類具有相同signature的方法。假設在SubCircle所在的空間PI=100,而面積公式也變?yōu)?PI*R*R*R。

    SubCircle.prototype.PI = 100

    SubCircle.prototype.area = function() {
       return this.PI*this.r*this.r*this.r;
    }
    Sc.area()

    這樣的操作可以認為是:

    Sc.PI->sc.prototype.PI->Cricle(0).PI = 100

    Sc.area()->sc.prototype.area()->Circle(0).area.
    這個時候,調用過程是這樣的

    sc.area()->sc.prototype.area(),在這里解釋器發(fā)現(xiàn)了area這個方法,于是它就調用此方法。

    而Cricle.prototype.area就永遠也不會被調用。PI的調用也是如此。那么子類如何想調用父類的方法應怎么辦呢?好像沒有什么辦 法哦,誰知道可以告訴我。但面向對象的理論告訴我們,繼承主要是提供接口而不是代碼復用,所以還是少有這樣的念頭為好 :)。

    下面是一個例子程序。包含上面的所有的概念。
    例子
    ///////////define: Cricle//////////////////
    function Circle(r) {
    this.r = r;
    }
    Circle.PI = 3.14;
    Circle.prototype.PI = 3.14;
    Circle.prototype.area = function() { return Circle.PI*this.r*this.r; }
    Circle.prototype.area2 = function() { return this.PI*this.r*this.r; }


    //// test
    c = new Circle(3);
    //alert("area1 :"+c.area());
    //alert("area2 :"+c.area2());

    Circle.max = function(a, b) { return a.r>b.r ? a.r : b.r; }
    //alert("max is "+Circle.max(new Circle(1), new Circle(3)));

    c1 = new Circle(1);
    c2 = new Circle(1);
    c2.PI = 100;//Circle.prototype.PI=100;

    //alert("c1.area1 "+c1.area());
    //alert("c1.area2 "+c1.area2());
    //alert("c2.area1 "+c2.area());
    //alert("c2.area2 "+c2.area2());

    ////////////////////////define: SubCircle //////////////////
    function SubCircle(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
    }
    SubCircle.prototype = new Circle(0);
    SubCircle.prototype.PI = 100;
    SubCircle.prototype.move2 = function(x, y) { this.x = x; this.y = y;}
    SubCircle.prototype.area = function() { return this.PI*this.r*this.r*this.r; }

    //// test
    sc = new SubCircle(0,0,2);

    alert(sc.area());

    主站蜘蛛池模板: 在线观看亚洲免费| 久久亚洲最大成人网4438| 男人的天堂av亚洲一区2区| 成人超污免费网站在线看| 亚洲毛片无码专区亚洲乱| 最近中文字幕大全免费视频| 91亚洲一区二区在线观看不卡| 免费福利电影在线观看| 亚洲成a人片在线观看无码| 大地资源网高清在线观看免费| 亚洲国产精品VA在线看黑人| 久久久久国色av免费看| 亚洲成无码人在线观看| 丁香花免费完整高清观看| 亚洲国产日韩精品| 又色又污又黄无遮挡的免费视| 曰批全过程免费视频观看免费软件| 亚洲色偷偷综合亚洲AV伊人| 三级网站在线免费观看| 亚洲天堂视频在线观看| 国产在线a免费观看| 亚洲av色香蕉一区二区三区蜜桃| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 亚洲综合伊人制服丝袜美腿| 大学生一级毛片免费看| 午夜亚洲WWW湿好爽| 在线a亚洲v天堂网2019无码| 久久久免费的精品| 亚洲中文字幕无码中文字| 亚洲国产成人久久一区WWW| 黄网站免费在线观看| 亚洲一卡2卡3卡4卡乱码 在线| 国产三级电影免费观看| 国产精品白浆在线观看免费| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 国产精品成人无码免费| 丝袜足液精子免费视频| 亚洲w码欧洲s码免费| 亚洲一区二区三区在线视频| 国产成人免费在线| 特级毛片爽www免费版|