高程3版中《寄生組合式繼承》中的一個錯誤

前言

最近一直在回顧js繼承方式,在閱讀《高級程序設計》第3版 的時候遇到一個問題,下面僅我的見解,若是有理解錯誤或者不一樣見解,歡迎一塊兒探討:函數

正文

何謂寄生組合繼承,實質上分爲兩步:this

  1. 將父類的原型對象賦值給子類的原型對象
  2. 將子類原型對象中的constructor指針指向子類構造函數

這樣就實現了繼承,具體代碼以下所示(書中原代碼):spa

function SuperType(name){
    this.name = name;
}

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

function SubType(name, age){
    SuperType.call(this, name);
    this.age = age;
}

function inheritPrototype(subType, superType){
    const subPrototype =  Object(superType.prototype);
    subPrototype.constructor = SubType;
    subType.prototype = subPrototype;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function(){
    console.log(this.age);
}

const sub_1 = new SubType('liumin', '23');

sub_1.sayName();
sub_1.sayAge();

在inheritPrototype函數當中正是完成了上面的兩個步驟,可是注意這裏是經過Object函數建立一個對象賦值給subPrototype的,接下來咱們瞭解一下Object函數prototype

Object函數

爲給定值建立一個對象包裝器,若是傳入的是undefined 或者 null,則返回一個空對象;不然返回一個給定值對應類型的對象;設計

console.log(Object(undefined));
    console.log(Object(null));
    console.log(Object('123'));
    console.log(Object(123));

輸出結果是:
圖片描述指針

若是傳入的參數是一個對象,那麼經過Object返回的則是對這個對象的引用,以下所示:code

const person = {
    name:'xiaohong',
    age:'23',
    grade:'12',
}

const anotherPerson = Object(person);
console.log(anotherPerson === person);

輸出結果:
圖片描述
person和anotherPerson引用的是同一塊內存地址,這與Object.create(obj)是有差異的,Object.create(obj)是在內存中新開闢一個空間對象

存在的問題

若是在上述的繼承方式中存在一個問題,若是以後經過子類的原型對象對父類中的sayName方法進行從新定義,這時候就會修改父類中的sayName方法,從而繼承父類的其餘子類中的sayName方法也就會被篡改掉,形成混亂。
例如:
假如定義第二個子類——SubTypeCopy:繼承

function SubTypeCopy(name, height){
    SuperType.call(this, name);
    this.height = height;
}
inheritPrototype(SubTypeCopy, SuperType);

而後在第一個子類中從新定義sayName方法:圖片

SubType.prototype.sayName = function(){
  console.log(`my name is:${this.name}`);
 }

const sub_1 = new SubType('liumin', '23');
const sub_2 = new SubTypeCopy('liujie','180');

sub_1.sayName();
sub_2.sayName();

最後的輸出結果是:
圖片描述

由此能夠看出,SubTypeCopy中的sayName方法也發生了改變,若是將Object替換成Object.create(obj)方法,就不會存在這樣的問題。

相關文章
相關標籤/搜索