JS繼承 -- 寄生式繼承 & 寄生組合式繼承


 

 

5.寄生式繼承

與寄生構造函數和工廠模式類似,創建一個僅用於封裝繼承過程的函數,該函數在內部以某種方式來增強對象,最后返回對象。

復制代碼
function createAnother(original){
    var clone = Object.create(original);    //通過調用函數創建一個新對象
    clone.sayHi = function(){               //以某種方式來增強這個對象
        alert("Hi");
    };
    
    return clone;                        //返回這個對象
}

var person = {
    name: "Bob",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();
復制代碼

在上述例子中,createAnother函數接收了一個參數,也就是將要作為新對象基礎的對象。

anotherPerson是基於person創建的一個新對象,新對象不僅具有person的所有屬性和方法,還有自己的sayHi()方法。

6.寄生組合式繼承

  組合繼承是js最常用的繼承模式,組合繼承最大的問題就是無論在什么情況下,都會調用兩次構造函數:一次是在創建子類型原型時,另一次是在子類型構造函數內部。

復制代碼
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
}

function SubType(name, age){
    SuperType.call(this, name);  //第二次調用SuperType()
    
    this.age = age;
}
SubType.prototype = new SuperType();  //第一次調用SuperType()
SubType.prototype.sayAge = function(){
    alert(this.age);
}
復制代碼

在第一次調用SuperType構造函數時,SubType.prototype會得到兩個屬性: name和colors; 他們都是SuperType的實例屬性,只不過現在位於SubType的原型中。

當調用SubType構造函數時,又會調用一次SuperType構造函數,這一次又在新對象上創建了實例屬性name和colors。

於是這兩個屬性就屏蔽了原型中的兩個同名屬性。

寄生組合式繼承就是為了解決這一問題。

通過借用構造函數來繼承屬性;

通過原型鏈來繼承方法。

不必為了指定子類型的原型而調用超類型的構造函數,

復制代碼
function inheritPrototype(subType, superType){
    var protoType = Object.create(superType.prototype);    //創建對象
    protoType.constructor = subType;                    //增強對象
    subType.prototype = protoType;                        //指定對象
}
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
}

function SubType(name, age){
    SuperType.call(this, name);  
    
    this.age = age;
}
inheritPrototype(SubType, SuperType)
SubType.prototype.sayAge = function(){
    alert(this.age);
}

var instance = new SubType("Bob", 18);
instance.sayName();
instance.sayAge();
復制代碼
inheritPrototype函數接收兩個參數:子類型構造函數和超類型構造函數。
1. 創建超類型原型的副本。
2. 為創建的副本添加constructor屬性,彌補因重寫原型而失去的默認的constructor屬性
3. 將新創建的對象(即副本)賦值給子類型的原型
這種方法只調用了一次SuperType構造函數,instanceof 和isPrototypeOf()也能正常使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM