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

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

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

    太陽(yáng)雨

    痛并快樂(lè)著

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      67 Posts :: 3 Stories :: 33 Comments :: 0 Trackbacks

    還是《Professional JavaScript for Web Developers》。
    JavaScript也可以對(duì)象繼承?當(dāng)我看到這一章第一個(gè)反應(yīng)便是這個(gè),以前從來(lái)沒有想過(guò)的,呵呵。
    JS實(shí)現(xiàn)繼承有如下幾種辦法:

    1. 對(duì)象冒充

    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的代碼行后定義。否則,可能會(huì)覆蓋超類的相關(guān)屬性和方法。
    然后。。。用這個(gè)方法,還可以實(shí)現(xiàn)多重繼承,哈哈哈

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

    不過(guò)這里有個(gè)小弊端,就是如果ClassX和ClassY有同名的屬性和方法的話,ClassY具有優(yōu)先級(jí),使用時(shí)要注意點(diǎn),呵呵。

    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.");

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

    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()方法后面帶的多個(gè)參數(shù)存入數(shù)組再進(jìn)行傳遞:

    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()方法實(shí)現(xiàn)繼承的代碼:

    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"

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

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


    這個(gè)。。黃色那一句還是比較神奇的,呵呵。
    不過(guò)要注意,調(diào)用ClassA的構(gòu)造函數(shù)時(shí),沒有給它傳遞參數(shù),這在原型鏈中是標(biāo)準(zhǔn)做法,要確保構(gòu)造函數(shù)沒有任何參數(shù)!
    同時(shí)要注意上面的代碼,和對(duì)象冒充類似,子類的所有的屬性和方法都必須出現(xiàn)在prototype屬性被賦值后,因?yàn)樵谒百x值的所有方法都會(huì)被刪除!
    原型鏈的好處在于可以使用類似如下代碼檢測(cè):

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

    而它的壞處在于不能多重繼承,不過(guò)用慣Java的人應(yīng)該比較習(xí)慣吧,呵呵。

    5. 混合方式

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

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

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

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

    posted on 2009-11-06 01:51 小蟲旺福 閱讀(206) 評(píng)論(0)  編輯  收藏 所屬分類: Javascript相關(guān)
    主站蜘蛛池模板: 国产亚洲色婷婷久久99精品| 免费一级大黄特色大片| 久久被窝电影亚洲爽爽爽| xxxx日本在线播放免费不卡| 四虎影视永久免费视频观看| 黄人成a动漫片免费网站| 亚洲福利中文字幕在线网址| 美女被吸屁股免费网站| 亚洲成A人片在线观看中文 | 亚洲欧洲精品成人久久奇米网 | 国产成人免费高清在线观看| 日韩欧美亚洲中文乱码| 免费A级毛片无码A| 久久久久久毛片免费看| 亚洲最大的成网4438| 免费观看黄色的网站| 亚洲欧美日韩中文字幕在线一区| 成人免费无码大片a毛片软件| 亚洲AV无码一区二区三区鸳鸯影院 | 亚洲人成色777777精品| 国产aa免费视频| 国产福利免费视频| 亚洲AV本道一区二区三区四区| 97视频免费在线| 亚洲GV天堂GV无码男同| 亚洲成a人一区二区三区| 国内永久免费crm系统z在线 | 美女视频黄a视频全免费网站色 | 亚洲国产精品美女| 日本免费中文字幕在线看| 春意影院午夜爽爽爽免费| 亚洲AV无码一区二区二三区入口| 最近2019年免费中文字幕高清 | 亚洲国产成人精品青青草原| 免费高清资源黄网站在线观看| 国产精品青草视频免费播放| 亚洲精品午夜视频| 免费看小12萝裸体视频国产| 亚洲成人免费在线| 免费观看亚洲人成网站| 911精品国产亚洲日本美国韩国|