javascript之繼承

本文內容,取自《Javascript高級程序設計》第三版,第六章bash

繼承

繼承主要靠原型鏈實現的。函數

原型鏈基本思想:利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。原型鏈的構建是經過將一個類型的實例賦值給另一個構造函數的原型實現的。ui

構造函數、原型、實例之間的關係:每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。this

原型式繼承

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}
function SubType(){
    this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
    return this.subproperty;
}

var instance = new SubType();
console.log(instance.getSuperValue()) //true
複製代碼

繼承實現的本質就是重寫原型對象。SubType.prototype等於SuperType的實例,實現SubType繼承SuperType。spa

getSuperType()方法仍然還在SupertType.prototype中,而property則位於SubType.prototype中,由於property是實例屬性,getSuperType()方法則是一個原型方法。instance屬於本身的屬性subproperty。

問題:SubType的原型被徹底重寫,SubType原型中的constructor屬性再也不指向SubType構造函數(指向了Base構造函數)prototype

全部函數的默認原型都是Object的實例。設計

組合式繼承

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);//借用構造函數
    this.age = age;
}
SubType.prototype = new SuperType();//原型
SubType.prototype.constructor = SubType;//可以識別是誰建立的對象
SubType.prototype.sayAge = function(){
    console.log(this.age);
}

var instance1 = new SubType('zhangsan', 25);
var instance2 = new SubType('lisi', 26);

instance1.colors.push('green');
console.log(instance1.colors) //['red', 'blue', 'green']
console.log(instance2.colors) //['red', 'blue']
複製代碼

原型鏈缺點:指針

第一,包含引用類型值的原型,修改問題;code

第二,在建立子類型的實例時,不能向超類型的構造函數傳遞參數。cdn

構造函數的缺點:

第一,不能識別出來是誰建立的;

第二,不能實現共享函數方法。

使用組合繼承,避免了原型鏈和構造函數的缺點,融合他們的有點優勢。

寄生組合式繼承

上面的模式有個問題,有兩組name和colors屬性,一組在實例上,一組在SubType原型中。這就是調用兩次SuperType的結果。

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);//借用構造函數
    this.age = age;
}
inheritPrototype(SubType, SuperType)//原型
SubType.prototype.sayAge = function(){
    console.log(this.age);
}
複製代碼
function inheritPrototype(subType, superType){
    var prototype = Object(superType.prototype);//
    prototype.constructor = subType;//可以識別是誰建立的對象
    subType.prototype;
}
複製代碼

寄生組合式繼承,經過構造函數實現繼承屬性,經過原型鏈實現繼承方法。基本思路:沒必要爲了指定子類型的原型而調用超類型的構造函數,咱們須要的無非就是超類型原型的一個副本而已。

總結:

全部函數的默認原型都是Object的實例。

原型鏈的構建,是經過將一個類型的實例賦值給另外一個構造函數的原型實現的。

原型鏈繼承共享的屬性和方法,經過借用構造函數繼承實例屬性。

相關文章
相關標籤/搜索