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

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

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

    太陽雨

    痛并快樂著

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      67 Posts :: 3 Stories :: 33 Comments :: 0 Trackbacks

    還是《Professional JavaScript for Web Developers》。
    JavaScript也可以對象繼承?當我看到這一章第一個反應便是這個,以前從來沒有想過的,呵呵。
    JS實現繼承有如下幾種辦法:

    1. 對象冒充

    function ClassA(sColor) {
      this.color = sColor;
      this.sayColor = function() {
        alert(this.color);
      };
    }
    function ClassB(sColor, sName) {
      this.newMethod = ClassA;
      this.newMethod(sColor);
      delete this.newMethod;
      this.name = sName;
      this.sayName = function() {
        alert(this.name);
      };

    }
    var objA = new ClassA("red");
    var objB = new ClassB("blue", "Nicholas");
    objA.sayColor();  //outputs "red"
    objB.sayColor();  //outputs "blue"
    objB.sayName();  //outputs "Nicholas"

    呵呵,是不是很有趣。注意黃色代碼,所有新的屬性和新的方法必須在刪除了newMethod的代碼行后定義。否則,可能會覆蓋超類的相關屬性和方法。
    然后。。。用這個方法,還可以實現多重繼承,哈哈哈

    function ClassZ() {
      this.newMethod = ClassX;
      this.newMethod();
      delete this.newMethod;
      this.newMethod = ClassY;
      this.newMethod();
      delete this.newMethod;
    }

    不過這里有個小弊端,就是如果ClassX和ClassY有同名的屬性和方法的話,ClassY具有優先級,使用時要注意點,呵呵。

    2. call()方法

    先看看call()方法的使用:

    function sayColor(sPrefix, sSuffix) {
      alert(sPrefix + this.color + sSuffix);
    };
    var obj = new Object();
    obj.color = "red";
    sayColor.call(obj, "The color is ", ", a very nice color indeed.");

    這個例子中,sayColor雖然在對象外定義,即使他不屬于任何對象,也可以引用關鍵字this。調用call()方法時,第一個參數是obj,說明應該賦予sayColor()函數中的參數的this關鍵字值是obj,第二個和第三個參數就是sayColor()函數本身的參數sPrefix和sSuffix
    要與冒充對象方法一起使用該方法,只需要將前三行的賦值、調用和刪除代碼替換即可:

    function ClassA(sColor) {
      this.color = sColor;
      this.sayColor = function() {
        alert(this.color);
      };
    }
    function ClassB(sColor, sName) {
      //this.newMethod = ClassA;
      //this.newMethod(sColor);
      //delete this.newMethod;
      ClassA.call(this, sColor);

      this.name = sName;
      this.sayName = function() {
        alert(this.name);
      };
    }
    var objA = new ClassA("red");
    var objB = new ClassB("blue", "Nicholas");
    objA.sayColor();  //outputs "red"
    objB.sayColor();  //outputs "blue"
    objB.sayName();  //outputs "Nicholas"

    3. apply()方法

    apply()方法和call()方法很相似,唯一不同的就是將call()方法后面帶的多個參數存入數組再進行傳遞:

    function sayColor(sPrefix, sSuffix) {
      alert(sPrefix + this.color + sSuffix);
    };
    var obj = new Object();
    obj.color = "red";
    sayColor.apply(obj, new Array("The color is ", ", a very nice color indeed."));

    自然,很容易得出用apply()方法實現繼承的代碼:

    function ClassA(sColor) {
      this.color = sColor;
      this.sayColor = function() {
        alert(this.color);
      };
    }
    function ClassB(sColor, sName) {
      //this.newMethod = ClassA;
      //this.newMethod(sColor);
      //delete this.newMethod;
      ClassA.apply(this, new Array(sColor));

      this.name = sName;
      this.sayName = function() {
        alert(this.name);
      };
    }
    var objA = new ClassA("red");
    var objB = new ClassB("blue", "Nicholas");
    objA.sayColor();  //outputs "red"
    objB.sayColor();  //outputs "blue"
    objB.sayName();  //outputs "Nicholas"

    其中,如果超類參數順序與子類相同,圖中黃色區域可以這么寫:

    ClassA.apply(this, arguments);

    4. 原型鏈

    function ClassA() {
    }
    ClassA.prototype.color = "red";
    ClassA.prototype.sayColor = function() {
      alert(this.color);
    };
    function ClassB() {
    }
    ClassB.prototype = new ClassA();
    ClassB.prototype.name = "Nichloas";
    ClassB.prototype.sayName = function() {
      alert(this.name);
    }


    這個。。黃色那一句還是比較神奇的,呵呵。
    不過要注意,調用ClassA的構造函數時,沒有給它傳遞參數,這在原型鏈中是標準做法,要確保構造函數沒有任何參數!
    同時要注意上面的代碼,和對象冒充類似,子類的所有的屬性和方法都必須出現在prototype屬性被賦值后,因為在它之前賦值的所有方法都會被刪除!
    原型鏈的好處在于可以使用類似如下代碼檢測:

    var objB = new ClassB();
    alert(objB instanceof ClassA)  //outputs "true"
    alert(objB instance of ClassB) //outputs "true"

    而它的壞處在于不能多重繼承,不過用慣Java的人應該比較習慣吧,呵呵。

    5. 混合方式

    總結以上幾種方式,對象冒充的問題是必須使用構造函數方式,這不是最好的選擇(參考我的另一片讀書筆記《讀書筆記之JavaScript的類編寫方法》)。但如果使用原型鏈,又無法使用帶參數的構造函數了。那么混合模式就是解決這兩個問題的最好答案了,呵呵:

    function ClassA(sColor) {
      this.color = sColor;
    }
    ClassA.prototype.sayColor = function() {
      alert(this.color);
    };
    function ClassB(sColor, sName) {
      ClassA.call(this, sColor);
      this.name = sName;
    }
    ClassB.prototype = new ClassA();
    ClassB.prototype.sayName = function() {
      alert(this.name);
    };

    這種方式是推薦使用的,呵呵。

    最后還是那句話,以上源代碼均來自Nicholas C. Zakas的《Professional JavaScript for Web Developers》

    posted on 2009-11-06 01:51 小蟲旺福 閱讀(215) 評論(0)  編輯  收藏 所屬分類: Javascript相關
    主站蜘蛛池模板: a级午夜毛片免费一区二区| a级毛片黄免费a级毛片| 亚洲色婷婷综合开心网| 免费人成在线观看网站| 亚洲av片不卡无码久久| 亚洲成av人片天堂网老年人| 免费av一区二区三区| 中文日韩亚洲欧美制服| 国产亚洲一区二区三区在线不卡 | 国产精品亚洲а∨无码播放麻豆 | 热久久精品免费视频| 中文字幕在线成人免费看| 亚洲人xxx日本人18| 国产亚洲人成A在线V网站| 毛片视频免费观看| 最新亚洲成av人免费看| 亚洲精品无码日韩国产不卡av| 在线精品亚洲一区二区小说| 久久久高清免费视频| 国产成人1024精品免费| 亚洲综合激情五月丁香六月| 亚洲AV无码国产精品色午友在线| 永久黄网站色视频免费直播| 国产精品免费一区二区三区四区| 天天综合亚洲色在线精品| 亚洲国产成人久久99精品| 亚洲熟妇丰满多毛XXXX| 在线观看免费大黄网站| 亚洲黄色免费电影| 成全视频在线观看免费| 免费无码专区毛片高潮喷水| 国产成人精品亚洲日本在线| 亚洲欧洲日产国产综合网| 亚洲精品国产高清不卡在线| 免费观看美女裸体网站| 国产精品免费观看| 久久永久免费人妻精品下载| 中文字幕在线免费观看视频| 一区二区三区免费在线观看| 老牛精品亚洲成av人片| 亚洲精品国产suv一区88|