javascript高級編程學習筆記(二)——繼承

寫讀書筆記的好處在於加深記憶,前一篇總結了編程中建立的對象的幾種方式,以及經常使用的方式,這一篇總結實現繼承的方式: 一、對象冒充:編程

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裏面使用。

學習小結:

因此最經常使用的實現繼承的方式是混合方式,有原型鏈也有冒充方式。
相關文章
相關標籤/搜索