原型鏈與繼承(一):六種常見繼承模式
阿新 • • 發佈:2018-11-28
一、原型鏈繼承:
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