我知道的Javascript繼承的6種方式

講解前需要明白的幾點(diǎn)

  1. Javascript繼承:繼承機(jī)制并沒有明確規(guī)定,完全由開發(fā)者決定最合適的繼承方式
  2. 類的原型對(duì)象上的所有屬性和方法都會(huì)被子類擁有
  3. this關(guān)鍵字:誰(shuí)調(diào)用這個(gè)屬性和方法this就指誰(shuí)

1. 對(duì)象冒充方式實(shí)現(xiàn)繼承(Object Masquerading)

  1. 對(duì)象冒充實(shí)現(xiàn)單繼承
function ClassA(sColor){
    this.name="Lily"
    this.color=sColor;
    this.sayColor=function () {
        console.log(this.color)
    }
}

function ClassB(sColor,sName) {
    //newMethod()之前定義同名屬性和方法會(huì)被父類覆蓋
    // this.name=sName;
    // this.sayColor=function () {
    //     alert(sColor);
    // }

    this.newMethod=ClassA;
    //調(diào)用方法后,相當(dāng)于給B類增加了sColor屬性和sayColor方法
    this.newMethod(sColor);

    //newMethod()之后同名方法會(huì)覆蓋父類
    this.sayColor=function () {
            alert(sColor);
    }
    // 從對(duì)象上刪除父類構(gòu)造函數(shù)
    delete this.newMethod;

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

子類中定義的屬性和方法如果在調(diào)用this.newMethod()這行代碼之前,那么子類同名屬性和方法會(huì)被父類覆蓋,反之會(huì)覆蓋父類同名屬性和方法,理由很簡(jiǎn)單,原來(lái)的賦值被新值覆蓋

  1. 對(duì)象冒充實(shí)現(xiàn)多繼承
function ClassC(sColor,sName){
    this.newMethod=ClassA;
    this.newMethod(sColor);
    delete this.newMethod;
    this.newMethod=ClassB;
    this.newMethod(sColor,sName);
    delete this.newMethod;
}
var obj=new ClassC("green","ClassC");

obj.sayName(); //ClassC
obj.sayColor(); // green

可見ClassC同時(shí)擁有ClassA和ClassB的特性
ClassA的同名屬性和方法會(huì)被ClassB覆蓋.同樣因?yàn)楹蠖x覆蓋了先定義

2. call()方法實(shí)現(xiàn)繼承

function sayColor(sPrefix,sSuffix){
    console.log(sPrefix+this.color+sSuffix);
}

var obj=new Object();
obj.color="blue";

//會(huì)調(diào)用sayColor方法
sayColor.call(obj,"The color is "," a very nice color indeed.");

//下面與對(duì)象冒充一起使用

function ClassB(sColor,sName) {
    // this.newMethod=ClassA;
    // this.newMethod(sColor);
    // delete this.newMethod;
    //call就是方法調(diào)用沒啥特別地方,做了上面三條語(yǔ)句做的事
    //調(diào)用構(gòu)造函數(shù)
    ClassA.call(this,sColor);

    this.name=sName;
    this.sayName=function () {
        console.log(this.name);
    }
}

3. apply()方法實(shí)現(xiàn)繼承

function sayColor(sPrefix,sSuffix){
    console.log(sPrefix+this.color+sSuffix);
}

var obj=new Object();
obj.color="blue";

// 普通的方法調(diào)用
sayColor.apply(obj,new Array("The color is ", " a very nice color indeed."));

function ClassB(sColor,sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    //調(diào)用構(gòu)造函數(shù)
    // ClassA.apply(this,arguments)
    ClassA.apply(this,new Array(sColor))
    this.name=sName;
    this.sayName=function () {
        console.log(this.name);
    }
}

var obj=new ClassB("red","Bill");
// 如果特意將ClassB的參數(shù)順序調(diào)整ClassA不同,這時(shí)就不能用arguments,該使用ClassA.apply(this,new Array(sColor)),感興趣自己試驗(yàn)一下
// ob.sayColor(); //Bill
obj.sayColor();

總結(jié):call()和apply()讓繼承變得更清爽,查看源碼你會(huì)發(fā)現(xiàn)是Function的原型方法。

4. 原型繼承

function object(o) {
    function F() {}
    F.prototype=o;
    return new F();
}
var person = {
    name:"EvanChen",
    friends:["Shelby","Court","Van"]
};

var person1=object(person);
//先從person1對(duì)象查找name,沒找到會(huì)去原型對(duì)象上查找
console.log(person1.name);

es5以后,規(guī)范了這種繼承,創(chuàng)建對(duì)象使用Object.create()

//只傳一個(gè)參數(shù)時(shí)
var person1=Object.create(person);
console.log(person1.name);

//傳兩個(gè)參數(shù)時(shí)
var prop={son:{age:10}};
var person1=Object.create(person,prop);

總結(jié):Object.create傳入的第一個(gè)參數(shù)屬性會(huì)作為person1的原型屬性。第二個(gè)參數(shù)屬性會(huì)作為person1對(duì)象上的屬性

5. 原型鏈繼承

function ClassA() {}
ClassA.prototype.color="blue";
ClassA.prototype.sayColor=function () {
    console.log(this.color);
}
function ClassB() {

}

ClassB.prototype=new ClassA();

var obj=new ClassB();
obj.sayColor(); //blue
console.log(obj.color); //blue

可見ClassB同時(shí)擁有了ClassA的屬性可方法

下面為ClassB添加更多原型方法

...
ClassB.prototype=new ClassA();

//下面的屬性和方法是在賦值ClassA為新原型之后添加的屬性和方法
ClassB.prototype.name="";
ClassB.prototype.sayName=function () {
    console.log(this.name);
}

var classB=new ClassB();
classB.color="red";
classB.name="John";
classB.sayColor(); //red
classB.sayName(); // John

特別指出:

  1. ClassB原型對(duì)象上添加的新的屬性和方法,請(qǐng)務(wù)必添加在ClassB.prototype=new ClassA()之后。因?yàn)樵鸵呀?jīng)指向ClassA,舊原型對(duì)象被銷毀
  2. 通過修改類的原型對(duì)象方式?jīng)]辦法實(shí)現(xiàn)多繼承,因?yàn)閷?duì)象的原型對(duì)象僅有一個(gè)
  3. 對(duì)象和對(duì)象的原型上有同名屬性或方法,優(yōu)先會(huì)使用對(duì)象本身,如果對(duì)象上無(wú)此屬性,才會(huì)使用原型對(duì)象上同名屬性和方法

6. 混合構(gòu)造函數(shù)和原型鏈方式實(shí)現(xiàn)繼承

function ClassA(sColor) {
    this.color=sColor;
}
ClassA.prototype.sayColor=function () {
    console.log(this.color);
}

function ClassB(sColor,sName) {
    ClassA.call(this,sColor);
    this.name=sName;
}

ClassB.prototype=new ClassA();
//為ClassB添加新原型方法
ClassB.prototype.sayName=function () {
    console.log(this.name);
}

var classA=new ClassA("purple");
var classB=new ClassB("red","John");

classA.sayColor(); // purple
classB.sayColor(); // red
classB.sayName(); // John

混合繼承結(jié)合了構(gòu)造函數(shù)創(chuàng)建各個(gè)對(duì)象擁有各自一份屬性和原型方法被所有對(duì)象共享的優(yōu)點(diǎn)

怎么樣簡(jiǎn)單吧,喜歡的話,幫忙點(diǎn)個(gè)贊O(∩_∩)O謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ECMAScript關(guān)鍵字 delete do else finally function in instance...
    doudou2閱讀 768評(píng)論 0 0
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,536評(píng)論 3 12
  • 對(duì)象冒充 構(gòu)造函數(shù)使用this關(guān)鍵字給所有屬性和方法賦值(即采用類聲明的構(gòu)造函數(shù)方式)。因?yàn)闃?gòu)造函數(shù)只是一個(gè)函數(shù),...
    bestvist閱讀 434評(píng)論 0 1
  • 普通創(chuàng)建對(duì)象和字面量創(chuàng)建對(duì)象不足之處:雖然 Object 構(gòu)造函數(shù)或?qū)ο笞置媪慷伎梢杂脕?lái)創(chuàng)建單個(gè)對(duì)象,但這些方式有...
    believedream閱讀 2,580評(píng)論 2 18
  • 我基本從來(lái)不寫工作的事兒。 因?yàn)楣ぷ鲗?shí)在沒啥好寫的,不就是工作唄。 然後今天打算稍微寫一點(diǎn),就寫JS吧。 我一直相...
    LostAbaddon閱讀 1,552評(píng)論 22 21

友情鏈接更多精彩內(nèi)容