02.Javascript中的繼承—-Inherits

來源:互聯網
上載者:User

 

02.Javascript中的繼承----Inherits

本文不再過多的闡述OOP中繼承的概念,只是用原生的Javascript代碼來類比類繼承(不是對象擴充)

類繼承:inherits

假設有已定義好的超類(父類)SuperClass和待繼承的子類SubClass,於是,可以定義如下的方法來實作類別繼承

inherits方法的定義

如下的這個inherits方法,其實現思想主要參考《Pro JavaScript Design Patterns》【Ross Harmes and Dustin Diaz】

/** * 這個方法用來實作類別繼承 * @param {function} subClass 待繼承的子類 * @param {function} superClass 待被繼承的父類 * @exception {Error} 參數不合法時拋出異常 */var inherits = function(subClass,superClass){    if(arguments.length !== 2){        throw new Error("必須明確的指定子類和父類");    }    for(var i = 0,n = arguments.length;i < n;i++){        if(typeof arguments[i] !== "function"){            throw new Errorr("所給的子類和父類必須都是function");        }    }    var F = function(){};    F.prototype = superClass.prototype;    subClass.prototype = new F();    subClass.prototype.constructor = subClass;    };

該方法的內部會進行嚴格的參數合法性檢查,參數必須是兩個,即一個子類,一個父類;另外還要求兩個參數都必須是function類型,否則拋出異常,宣告繼承失敗

inherits方法的使用▲第一步
/** * 定義父類 */var SuperClass = function(){};SuperClass.prototype = {    name : "趙先烈",    talk : function(){        alert("我的名字叫" + this.name);    }};    /** * 這裡定義子類 */var SubClass = function(){};    //實施繼承inherits(SubClass,SuperClass);//建立子類並從調用從子類繼承過來的方法var oSub = new SubClass();oSub.talk();    //這裡輸出:我的名字叫趙先烈

從程式的執行結果可以看出,這種繼承方法是將父類中的全部內容(除構造器以外)拷貝到子類中來,順利的完成了類繼承。

▲第二步
/** * 這裡定義父類 */var SuperClass = function(){    this.name = "趙先烈";    this.talk = function(){        alert("我的名字叫" + this.name);    };};/** * 這裡定義子類 */var SubClass = function(){    //這是一個空類};//實施繼承inherits(SubClass,SuperClass);//建立子類對象,並調用從父類繼承過來的方法var oSub = new SubClass();oSub.talk();    //按照繼承的概念,這裡應該輸出:我的名字叫趙先烈

程式真正執行後,才發現發生異常了,原因:在oSub執行個體中不存在talk方法。不是已經通過inherits方法實現繼承了麼,為什麼會沒有這個
方法呢?探究其原因,是因為在inherits的內部,只是將SuperClass的原型鏈原樣的拷貝給了SubClass,而不在SuperClass
原型鏈中的屬性及方法,子類就拿不到了。

那麼,既要支援第一種繼承,也要能滿足第二種,我們只能再次對inherits方法進行升級了,將其改為如下形式:

/** * 這個方法用來實作類別繼承 * @param {function} subClass 待繼承的子類 * @param {function} superClass 待被繼承的父類 * @exception {Error} 參數不合法時拋出異常 */var inherits = function(subClass,superClass){    if(arguments.length !== 2){        throw new Error("必須明確的指定子類和父類");    }    for(var i = 0,n = arguments.length;i < n;i++){        if(typeof arguments[i] !== "function"){            throw new Errorr("所給的子類和父類必須都是function");        }    }    subClass.prototype = new superClass();    subClass.prototype.constructor = subClass;};

經過這樣的改動,第一步和第二步中的情況就都能順利的正常的執行了。

▲第三步

如果在第二步的基礎上,將代碼中的SubClass.prototype改為如下形式:

SubClass.prototype = {    walk : function(){         alert("偶也,我可以走路了哎");    },    talk : function(){        alert("我的名字不叫" + this.name);    }

};

再執行如下代碼:

inherits(SubClass,SuperClass);var oSub = new SubClass();oSub.talk();    //這裡仍然輸出:我的名字叫趙先烈//重點在下面這句oSub.walk();    //這裡會拋出異常,告訴我們,walk方法不存在

分析這個結果,oSub.talk()的輸出應該為:我的名字不叫趙先烈。並且oSub.walk()也應該有輸出,程式應該正常執行才對。但是,為什麼會有這樣的運行結果呢?

這到底是為什麼呢?相信你一定早就發現了,在inherits方法中有這樣一句關鍵的代碼:

subClass.prototype = new superClass();

這裡已經告訴我們,原來,子類中的原型鏈已經被完全替換了,其實仔細說起來,這樣做是有違繼承的原則的(一般不都是子類覆蓋父類嗎?怎麼
反過來了呢)。

但是這樣的問題我們始終要解決,必須讓這個所謂的繼承能同時滿足以上三種情況都能正常執行。苦思冥想後,決定改成這樣:

/** * 這個方法用來實作類別繼承 * @param {function} subClass 待繼承的子類 * @param {function} superClass 待被繼承的父類 * @exception {Error} 參數不合法時拋出異常 */var inherits = function(subClass,superClass){    if(arguments.length !== 2){        throw new Error("必須明確的指定子類和父類");    }    for(var i = 0,n = arguments.length;i < n;i++){       if(typeof arguments[i] !== "function"){            throw new Errorr("所給的子類和父類必須都是function");        }    }    var oSuper = new superClass();    for(var key in oSuper){        if(!subClass.prototype[key]){            subClass.prototype[key] = oSuper[key];        }    }    subClass.prototype.constructor = subClass;};

OK,通過這樣的升級,再次運行上面的代碼,順利通過了。

上面這個通過兩次升級的inherits方法也是目前比較穩定的版本了,在後續的文章中所指的inherits方法,就是這個了。

本文旨在共同探討Javascript中類的繼承方式,只是其中的一種類比方式,類比之不當,還請見諒。

歡迎提出寶貴的升級建議。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.