1. 程式人生 > >原型鏈與繼承(一):六種常見繼承模式

原型鏈與繼承(一):六種常見繼承模式

一、原型鏈繼承:

function SuperType(){
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.Fun = function(){
 
};
function SubType(){
}
//繼承了SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green,black"

優點:能通過instanceOf和isPrototypeOf的檢測

注意:給原型新增方法的語句一定要放在原型替換SubType.prototype = new SuperType();之後

缺點:(1)SuperType中的屬性(不是方法)也變成了SubType的prototype中的公用屬性,如上面例子中的color屬性,可以同時被instance1和instance2修改
(2)建立子型別的時候,不能像父型別的建構函式中傳遞引數。

二、借用建構函式(常用方法)

function SuperType(){
    this.colors = ["red", "blue", "green"];
}
function SubType(){
    //繼承了SuperType
    SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert
(instance2.colors); //"red,blue,green" function SuperType(name){ this.name = name; } function SubType(){ //繼承了SuperType,同時還傳遞了引數 SuperType.call(this, "Nicholas"); //例項屬性 this.age = 29; } var instance = new SubType(); alert(instance.name); //"Nicholas"; alert(instance.age); //29

原理:在子型別建構函式的內部呼叫超型別建構函式
優點:解決了superType中的私有屬性變公有的問題,可以傳遞引數
缺點:方法在函式中定義,無法得到複用

三、組合繼承:

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;
}
SubType.prototype = new SuperType();//借用原型鏈繼承方法,一次呼叫
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

優點:繼承前兩者的優點,能通過instanceOf和isPrototypeOf的檢測
缺點:兩次呼叫父構造器函式,浪費記憶體。

四、原型式繼承:

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}

使用場合:沒必要構建建構函式,僅僅是想模擬一個物件的時候

五、寄生繼承:

function createAnother(original){
    var clone = object(original); //通過呼叫函式建立一個新物件
    clone.sayHi = function(){ //以某種方式來增強這個物件
        alert("hi");
    };
    return clone; //返回這個物件
}
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"

缺點:方法在函式中定義,無法得到複用

六:寄生組合繼承(最理想):

function inheritPrototype(subType, superType){
    var prototype = object(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);
};

轉載出處: https://blog.csdn.net/zhuanyemanong/article/details/80325387