|
??? 作者:Flyingis
??? 繼承是面向對象語言基本特征之一,通過繼承可以將父類所具有的特性遺傳到子類。ECMAScript中的繼承不像Java、C++等語言那么明顯,直接通過關鍵字來實現,通常它是通過模擬方式來實現繼承功能的,并且實現方式有多種。
??? 在繼承中引入this關鍵字,使用構造器方法定義類來實現繼承。一個構造器是一個函數,因此可以將父類的構造器作為子類的一個方法使用并進行調用。
function
ClassA(id)
{
??
this
.id
=
id;
 ??
this
.sayId
=?function() {
???? alert(this.id);
?? };
}
function
ClassB(id,?name)
{
??
this
.newMethod
=
ClassA;
??
this
.newMethod(id);
??
delete?this.newMethod;

??this.name= name;
 ??this.sayName=?function() {
???? alert(this.name);
?? };
}
??? 注意,子類中所有新的屬性和方法都必需在刪除newMethod后引入,否則,可能存在用父類的屬性和方法重寫子類屬性和方法的危險。另外,使用這種方法還可以實現多重繼承,此時如果兩個父類具有相同的屬性或方法時,最后的類具有優先級。由于這種繼承方法比較流行,ECMAScript第三版引入了兩個Function對象:call()和apply()。
??? call()
??? call()方法是最接近上述繼承方式的方法,它的第一個參數是this指向的對象,所有的其他參數都直接傳到function。
??? 用call()方法來實現繼承,只需要this.newMethod相關的三行代碼。
function
ClassB(id,?name)
{
???
//this.newMethod?=?ClassA;
??//this.newMethod(id);
??//delete?this.newMethod;
??ClassA.call(this,?id);??//this指向ClassB的對象

??this.name =name;
 ??this.sayName =?function()?{
???? alert(this.name);
?? };
}
??? apply()
??? apply()方法需要兩個參數:this所指向的對象,和傳到function的由參數組成的array。
 function?sayMessage(first,?last)?? {
??alert(first?+?this.logic?+last);
};

var?obj?=?new?Object();
obj.logic?=?"or";

sayMessage.apply(obj,?new?Array("Coffee?",?"?Tea"));??//輸出"Coffee?or?Tea"
?? ??? 同樣,使用 apply() 實現繼承可以通過如下方法實現。
 function?ClassB(id,?name)? {
??//this.newMethod?=?ClassA;
??//this.newMethod(id);
??//delete?this.newMethod;
??ClassA.apply(this,?new?Array(id));??//this指向ClassB的對象

??this.name?=?name;
 ??this.sayName?=?function()? {
????alert(this.name);
??};
}
??? 當父類構造器的參數和子類構造器參數的順序一致時,可以使用子類的arguments對象作為第二個參數。否則,必需創建一個array來傳遞參數,或是使用call()方法。
??? 文章待續……
|