<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 小蟲旺福 閱讀(206) 評論(0)  編輯  收藏 所屬分類: Javascript相關
    主站蜘蛛池模板: 久久精品亚洲乱码伦伦中文| 国产成人aaa在线视频免费观看| 国产成人亚洲精品影院| 朝桐光亚洲专区在线中文字幕| 免费的一级黄色片| 亚洲情A成黄在线观看动漫软件| 成人毛片免费观看视频在线 | 亚洲美女色在线欧洲美女| 99久热只有精品视频免费看| 亚洲综合激情九月婷婷| 一二三四影视在线看片免费| 亚洲日韩一区精品射精| 亚洲不卡AV影片在线播放| www一区二区www免费| 亚洲高清国产AV拍精品青青草原| 免费一级毛片无毒不卡| 亚洲国产视频一区| 免费看片A级毛片免费看| 永久免费观看黄网站| 亚洲AV午夜成人片| 中文字幕无码免费久久99| 国产成人精品亚洲| 国产AV无码专区亚洲A∨毛片| 日本免费网站视频www区| 亚洲AV色欲色欲WWW| 在线观看亚洲精品福利片| 99re视频精品全部免费| 亚洲情A成黄在线观看动漫软件| 日本中文一区二区三区亚洲 | 亚洲免费网站在线观看| 亚洲大码熟女在线观看| 亚洲熟妇av一区二区三区漫画| 麻豆高清免费国产一区| 精品国产日韩亚洲一区在线 | 亚洲精品无码专区久久久| 国产成人精品免费视频大全麻豆| 99亚洲乱人伦aⅴ精品| 亚洲AV人人澡人人爽人人夜夜| 青青视频观看免费99| 国产免费人成视频尤勿视频| 亚洲电影国产一区|