基于JavaScript實(shí)現(xiàn)繼承機(jī)制之構(gòu)造函數(shù)方法對(duì)象冒充的使用詳解
繼承的方式
ECMAScript 實(shí)現(xiàn)繼承的方式不止一種。這是因?yàn)?JavaScript 中的繼承機(jī)制并不是明確規(guī)定的,而是通過(guò)模仿實(shí)現(xiàn)的。這意味著所有的繼承細(xì)節(jié)并非完全由解釋程序處理。作為開(kāi)發(fā)者,你有權(quán)決定最適用的繼承方式。最原始的繼承實(shí)現(xiàn)方式就是對(duì)象冒充,下面著重介紹該方法。
對(duì)象冒充
對(duì)象冒充實(shí)現(xiàn)繼承的核心其實(shí)依賴于在函數(shù)環(huán)境中使用 this 關(guān)鍵字。其原理如下:構(gòu)造函數(shù)使用 this 關(guān)鍵字給所有屬性和方法賦值(即采用類聲明的構(gòu)造函數(shù)方式)。因?yàn)闃?gòu)造函數(shù)只是一個(gè)函數(shù),所以可使 ClassA 構(gòu)造函數(shù)成為 ClassB 的方法,然后調(diào)用它。ClassB 就會(huì)收到 ClassA 的構(gòu)造函數(shù)中定義的屬性和方法。例如,用下面的方式定義 ClassA 和 ClassB:
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
}
function ClassB(sColor) {
}
關(guān)鍵字 this 引用的是構(gòu)造函數(shù)當(dāng)前創(chuàng)建的對(duì)象。不過(guò)在這個(gè)方法中,this 指向的所屬的對(duì)象。這個(gè)原理是把 ClassA 作為常規(guī)函數(shù)來(lái)建立繼承機(jī)制,而不是作為構(gòu)造函數(shù)。如下使用構(gòu)造函數(shù) ClassB 可以實(shí)現(xiàn)繼承機(jī)制:
function ClassB(sColor) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
}
在這段代碼中,為 ClassA 賦予了方法 newMethod(請(qǐng)記住,函數(shù)名只是指向它的指針)。然后調(diào)用該方法,傳遞給它的是 ClassB 構(gòu)造函數(shù)的參數(shù) sColor。最后一行代碼刪除了對(duì) ClassA 的引用,這樣以后就不能再調(diào)用它。
所有新屬性和新方法都必須在刪除了新方法的代碼行后定義。否則,可能會(huì)覆蓋超類的相關(guān)屬性和方法:
function ClassB(sColor, sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
為證明前面的代碼有效,可以運(yùn)行下面的例子:
var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor(); //輸出 "blue"
objB.sayColor(); //輸出 "red"
objB.sayName(); //輸出 "John"
對(duì)象冒充可以實(shí)現(xiàn)多重繼承
有趣的是,對(duì)象冒充可以支持多重繼承。例如,如果存在兩個(gè)類 ClassX 和 ClassY,ClassZ 想繼承這兩個(gè)類,可以使用下面的代碼:
function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
這里存在一個(gè)弊端,如果存在兩個(gè)類 ClassX 和 ClassY 具有同名的屬性或方法,ClassY 具有高優(yōu)先級(jí)。因?yàn)樗鼜暮竺娴念惱^承。除這點(diǎn)小問(wèn)題之外,用對(duì)象冒充實(shí)現(xiàn)多重繼承機(jī)制輕而易舉。
由于這種繼承方法的流行,ECMAScript 的第三版為 Function 對(duì)象加入了兩個(gè)方法,即 call() 和 apply()。后來(lái)很多衍生出來(lái)的實(shí)現(xiàn)繼承的方法其實(shí)也是基于call() 和 apply()來(lái)實(shí)現(xiàn)的。
相關(guān)文章
關(guān)于uni-app頁(yè)面Page和組件Component生命周期執(zhí)行的先后順序
這篇文章主要介紹了關(guān)于uni-app頁(yè)面Page和組件Component生命周期執(zhí)行的先后順序,文中提供了具體的代碼,還不清楚的朋友可以來(lái)學(xué)習(xí)一下2023-04-04現(xiàn)如今最流行的JavaScript代碼規(guī)范
流行的雖然不一定是好的,但是從交流的角度來(lái)說(shuō),按照流行的風(fēng)格編寫代碼,可以讓你的代碼在大多數(shù)人看起來(lái)更習(xí)慣2014-03-03js函數(shù)中onmousedown和onclick的區(qū)別和聯(lián)系探討
了解這兩個(gè)事件的區(qū)別,但是實(shí)際并沒(méi)有使用到這兩個(gè)事件的區(qū)別去做一些操作,通常使用onclick的時(shí)候也可以使用onmousedown,使用onclick的時(shí)候更多一些2013-05-05javascript獲得當(dāng)前的信息的一些常用命令
這篇文章主要介紹了javascript獲得當(dāng)前的信息的一些常用命令,需要的朋友可以參考下2015-02-02js阻止默認(rèn)事件與js阻止事件冒泡示例分享 js阻止冒泡事件
嵌套的div元素,如果父級(jí)和子元素都綁定了一些事件,那么在點(diǎn)擊最內(nèi)層子元素時(shí)可能會(huì)觸發(fā)父級(jí)元素的事件,下面介紹一下js阻止默認(rèn)事件與js阻止事件冒泡示例,大家參考使用吧2014-01-01分享我學(xué)習(xí)js的過(guò)程 作者aircy javascript學(xué)習(xí)教程
分享我學(xué)習(xí)js的過(guò)程 作者aircy javascript學(xué)習(xí)教程...2007-02-02