溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript的繼承方式是什么

發(fā)布時間:2022-05-11 10:16:32 來源:億速云 閱讀:125 作者:zzz 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“JavaScript的繼承方式是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“JavaScript的繼承方式是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

JavaScript中的繼承方式

問:JavaScript中有幾種繼承方式呢

emmm...六種?五種?還是四種來著...

這次記清楚了 一共有五種繼承方式

  • 盜用構(gòu)造函數(shù) (經(jīng)典繼承方式 )

  • 組合繼承

  • 原型鏈?zhǔn)嚼^承

  • 寄生式繼承

  • 寄生式組合繼承

問:每種繼承方式是怎么實現(xiàn)的呢

盜用構(gòu)造函數(shù)

基本思路很簡單:在子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù)。因為畢竟函數(shù)就是在特定上下文中執(zhí)行代碼的簡單對象,所以可以使用apply() 和 call() 方法以新創(chuàng)建的對象為上下文執(zhí)行構(gòu)造函數(shù)。

盜用構(gòu)造函數(shù)的一個優(yōu)點就是可以在子類構(gòu)造函數(shù)中向父類構(gòu)造函數(shù)傳參

function SuperType(name) {
  this.name = name
  this.sayName = function () {
      console.log(this.name);
  }
}
function SubType(name, age) {
  //  繼承 SuperType 并傳參
  SuperType.call(this, name);
  //實例屬性
  this.age = age
}
let instance1 = new SubType('zxc', 2)
let instance2 = new SuperType('gyx')
// instance1.sayHi() // ?類也不能訪問父類原型上定義的方法,因此所有類型只能使用構(gòu)造函數(shù)模式
console.log(instance1);  // SubType { name: 'zxc', sayName: [Function (anonymous)], age: 2 }

組合繼承

組合繼承(有時候也叫偽經(jīng)典繼承)綜合了原型鏈和盜用構(gòu)造函數(shù),將兩者的優(yōu)點集中了起來。基 本的思路是使用原型鏈繼承原型上的屬性和方法,而通過盜用構(gòu)造函數(shù)繼承實例屬性。 這樣既可以把方 法定義在原型上以實現(xiàn)重用,又可以讓每個實例都有自己的屬性。

function SuperType(name) {
    this.name = name
    this.colors = ['red', 'blue', 'green']
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}
function SubType(name, age) {
    //繼承實例屬性
    SuperType.call(this, name)
    this.age = age
}
//繼承原型方法
SubType.prototype = new SuperType() 
SubType.prototype.sayAge = function () {
    console.log(this.age);
}
let instance1 = new SubType('zxc', '22')
instance1.sayName()  //zxc
instance1.sayAge()   // 22
let instance2 = new SubType("Greg", 27);
console.log(instance2.colors); // "red,blue,green"
instance2.sayName(); // "Greg";
instance2.sayAge(); // 27

原型鏈?zhǔn)嚼^承

原型式繼承適用于這種情況:你有一個對象,想在它的基礎(chǔ)上再創(chuàng)建一個新對象。你需要把這個對象先傳給 object() ,然后再對返回的對象進(jìn)行適當(dāng)修改。

Object.create() 方法將原型式繼承的概念規(guī)范化了 這個方法接收兩個參數(shù):作為新對象原型的對象,以及給新對象定義額外屬性的對象(第二個可選)

let person = {
   name: "Nicholas",
   age: 12,
   friends: ["Shelby", "Court", "Van"]
};
let anotherPerson1 = Object.create(person);
anotherPerson1.name = 'lll'  
anotherPerson1.friends.push('zxc') 
console.log(anotherPerson1);   // { name: 'lll' }
console.log(person.friends); //[ 'Shelby', 'Court', 'Van', 'zxc' ]

// ? Object.create() 的第二個參數(shù)與 Object.defineProperties() 的第二個參數(shù)一樣:每個新增屬性都通過各自的描述符來描述

let anotherPerson = Object.create(person, {
    name: {
        value: "Greg"
    }
});
console.log(anotherPerson.name); // "Greg"

寄生式繼承

寄生式繼承背后的思路類似于寄生構(gòu)造函數(shù)和工廠模式:創(chuàng)建一個實現(xiàn)繼承的函數(shù),以某種方式增強對象,然后返回這個對象。

function createAnother(original) {
    //通過調(diào)用函數(shù)創(chuàng)建一個對象
    let clone = Object(original)
    clone.sayHi = function () { // 以某種方式增強這個對象
        console.log("hi");
    };
    clone.sayName = function () { // 以某種方式增強這個對象
        console.log(this.name);
    };
    return clone; // 返回這個對象
}
let person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
let anotherPerson = createAnother(person);
anotherPerson.sayHi(); // "hi"
anotherPerson.sayName(); // "hi"

寄生時組合繼承

function SuperType(name) {
    this.name = name
    this.colors = ['red', 'blue']
}
SuperType.prototype.sayName = function () {
    console.log(this.name)
}
function SubType(name, age) {
    SuperType.call(this, name); // 第二次調(diào)用 SuperType()
    this.age = age;
}
SubType.prototype = new SuperType(); // 第一次調(diào)用 SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
    console.log(this.age);
};
let instance1 = new SubType('zxc', 12)
console.log(instance1);

在上面的代碼執(zhí)行后, SubType.prototype上會有兩個屬性: name 和 colors 。它們都是 SuperType 的實例屬性,但現(xiàn)在成為了 SubType 的原型屬性。在調(diào)用 SubType構(gòu)造函數(shù)時,也會調(diào)用SuperType 構(gòu)造函數(shù),這一次會在新對象上創(chuàng)建實例屬性 name 和 colors 。這兩個實例屬性會遮蔽原型上同名的屬性。

JavaScript的繼承方式是什么

JavaScript的繼承方式是什么

如圖所示,有兩組 name 和 colors 屬性:一組在實例上,另一組在 SubType 的原型上。這是 調(diào)用兩次 SuperType 構(gòu)造函數(shù)的結(jié)果,好在有辦法解決這個問題。

寄生式組合繼承通過盜用構(gòu)造函數(shù)繼承屬性,但使用混合式原型鏈繼承方法?;舅悸肥?strong>不通過調(diào) 用父類構(gòu)造函數(shù)給子類原型賦值,而是取得父類原型的一個副本。說到底就是使用寄生式繼承來繼承父 類原型,然后將返回的新對象賦值給子類原型。寄生式組合繼承的基本模式如下所示:

function inheritPrototype(subType, superType) {
    let prototype = object(superType.prototype); // 創(chuàng)建對象
    prototype.constructor = subType; // 增強對象
    subType.prototype = prototype; // 賦值對象
}

這個 inheritPrototype() 函數(shù)實現(xiàn)了寄生式組合繼承的核心邏輯。這個函數(shù)接收兩個參數(shù):子 類構(gòu)造函數(shù)和父類構(gòu)造函數(shù)。在這個函數(shù)內(nèi)部,第一步是創(chuàng)建父類原型的一個副本。然后,給返回的 prototype 對象設(shè)置 constructor 屬性,解決由于重寫原型導(dǎo)致默認(rèn) constructor 丟失的問題。最 后將新創(chuàng)建的對象賦值給子類型的原型。如下例所示,調(diào)用 inheritPrototype() 就可以實現(xiàn)前面例 子中的子類型原型賦值:

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}
function SubType(name, age) {
    SuperType.call(this, name)
    this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function () {
    console.log(this.age);
};

這里只調(diào)用了一次 SuperType 構(gòu)造函數(shù),避免了 SubType.prototype 上不必要也用不到的屬性, 因此可以說這個例子的效率更高。而且,原型鏈仍然保持不變,因此 instanceof 操作符和 isPrototypeOf() 方法正常有效。寄生式組合繼承可以算是引用類型繼承的最佳模式。

讀到這里,這篇“JavaScript的繼承方式是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI