寫讀書筆記的好處在於加深記憶,前一篇總結了編程中建立的對象的幾種方式,以及經常使用的方式,這一篇總結實現繼承的方式: 一、對象冒充:編程
function ClassA(sColor) {數組
this.color = sColor; this.sayColor = function () { alert(this.color); };
}app
function ClassB(sColor, sName) {函數
this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod; this.name = sName; this.sayName = function () { alert(this.name); };
}學習
var objA = new ClassA("blue");this
var objB = new ClassB("red", "John");prototype
objA.sayColor(); //輸出 "blue"code
objB.sayColor(); //輸出 "red"對象
objB.sayName(); //輸出 "John"繼承
對象冒充能夠實現多重繼承:
function ClassZ() {
this.newMethod = ClassX; this.newMethod(); delete this.newMethod; this.newMethod = ClassY; this.newMethod(); delete this.newMethod;
}
ECMAScript 的第三版爲 Function 對象加入了兩個方法,即 call() 和 apply()
二、使用call()方法(與經典的對象冒充方法最類似的方法)
function sayColor(sPrefix,sSuffix) {
alert(sPrefix + **this.color** + sSuffix);
};
var obj = new Object();
obj.color = "blue";
sayColor.call(obj, "The color is ", "a very nice color indeed.");
裏面的this.color的this就是obj
function ClassB(sColor, sName) {
//this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.call(this, sColor); //執行對象ClassA裏面的this.color和this.sayColor語句,並且this表明傳入的ClassB,這樣就爲ClassB添加了兩個成員 this.name = sName; this.sayName = function () { alert(this.name); };
}
三、使用apply()方法
apply方法和call方法很相似,
apply方法的使用以下:
function sayColor(sPrefix,sSuffix) {
alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "blue";
sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));
建立ClassB的時候可使用:
(1) function ClassB(sColor, sName) {
//this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.apply(this, new Array(sColor)); this.name = sName; this.sayName = function () { alert(this.name); };
}
(2) function ClassB(sColor, sName) {
//this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.apply(this, arguments); this.name = sName; this.sayName = function () { alert(this.name); };
}
能夠看到只是出入對象的參數不一樣而已的,使用的數組或者arguments
四、使用原型鏈
(1) function ClassA() {
}
ClassA.prototype.color = "blue";
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB() {
}
ClassB.prototype = new ClassA();
(2)
function ClassB() {
}
ClassB.prototype = new ClassA();
//若是上面的這句代碼(ClassB.prototype = new ClassA(); ),在下面的兩句代碼以後的話,那麼添加的name,sayName成員都會丟失
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
};
因此在使用這種方式的時候要注意順序
使用原型鏈的時候還可使用instanceof: var objB = new ClassB();
alert(objB instanceof ClassA); //輸出 "true"
alert(objB instanceof ClassB); //輸出 "true"
可是使用原型鏈的弊端是不支持多重繼承,原型鏈會用另外一類型的對象重寫類的 prototype 屬性。
五、混合方式
若是用對象冒充的話就必須使用構造函數方法,因此不是最好的選擇,可是使用原型鏈的話沒法使用帶參數的構造函數 ,好比使用原型鏈裏面的(2)代碼,ClassA若是是構造函數,那麼建立對象的時候就要先執行 ClassB.prototype = new ClassA(XXX);
再執行: ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
};
這樣是不現實的,由於你是先把ClassB的原型方法定義好了的,使用的時候要直接建立實例 ,這樣就不能參數傳入ClassA,因此最後採用了混合方式(以下)
function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor); this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () {
alert(this.name);
};
使用這種方式的時候,能夠經過建立ClassB時候傳入的參數再傳入到ClassA裏面使用。
學習小結:
因此最經常使用的實現繼承的方式是混合方式,有原型鏈也有冒充方式。