|
函數式編程語言可以實現面向對象編程,這是毫無疑義的,Curry方法可以實現對類和對象的模擬。但是JavaScript提供了另一種實現OOP的方法:原型繼承。
因此,JavaScript實現面向對象編程和一般的函數式編程語言還是有所區別的。
本文我將會給大家介紹JavaScript實現單繼承和多繼承的方法。
用原型實現單繼承:
有很多JavaScript庫提供了一些函數幫助實現單繼承。但實際上,JavaScript本身就提供了原型繼承的方法。因此,根本不需要提供特定的方法來實現,簡單使用JavaScript代碼就可以實現單繼承。
但是,JavaScript提供的原型繼承方法很容易犯錯,下面我給大家演示一下怎樣簡潔明了地實現原型繼承。
假設MyB繼承MyA類,那么,代碼如下:
function MyA(){
if(MyA.prototype.baseClass!==undefined){
MyA.prototype.baseClass.call(this);
}
……一般代碼
}
function MyB(){
if(MyB.prototype.baseClass!==undefined){
MyB.prototype.baseClass.call(this);
}
……一般代碼
}
MyB.prototype=new MyA();
MyB.prototype.baseClass=MyB.prototype.constructor;//使用baseClass引用//基類的構造器函數。
MyB.prototype.constructor=MyB;//恢復子類的構造器屬性 用于未來通過這個屬性判//斷對象的類型。
var myA=new MyA();
var myB=new MyB();
上述Javascript代碼中,我在每一個構造函數中都添加了這么一段代碼:
if(ClassName.prototype.baseClass!==undefined){
ClassName.prototype.baseClass.call(this);
}
這段代碼尋找原型中的baseClass方法,如果有,就調用它。
在后面的原型繼承的實現中,我為子類創建了baseClass屬性,它的值是基類的構造函數。因此,只要遵守我的方式編寫代碼,就可以保證基類的構造函數在子類構造實例時會得到執行。
現在,如果MyA類又繼承了Base類,只需要添加3行原型繼承代碼即可:
MyA.prototype=new Base();
MyA.prototype.baseClass= MyA.prototype.constructor;//使用baseClass引用//基類的構造器函數。
MyA.prototype.constructor= MyA;//恢復子類的構造器屬性 用于未來通過這個屬性判//斷對象的類型。
不需要修改MyA類本身的代碼,MyA類及其子類MyB類的實例就都可以得到正確的執行。
那些JavaScript庫實現的繼承,需要修改Object,Function等基類,容易引起沖突。還有一些方法,每一次實現繼承,都必須手工修改子類的構造函數,以使構造函數能夠正確調用基類的構造函數。
上面提供的方法編寫JavaScript代碼很好地解決了這些問題。
用Mixin(混入)實現多繼承
JavaScript本身并沒有提供多繼承的機制,但我們可以使用Mixin(混入)這種技巧實現多繼承的效果。
下面是我編寫的Mixin助手方法,可以為類和對象動態添加屬性。
1,copyClassPrototypeProperties復制類的原型屬性
/**
* 把源類原型上的所有屬性復制到目標對象上,第一個參數是boolean值,表示是否覆蓋目標類的原型的屬性
*/
function copyClassPrototypeProperties(isOverride,receivingClass,givingClass){
if(arguments.length>3){
for(var i=3;i<arguments.length;i++){
receivingClass.prototype[arguments[i]]=givingClass.prototype[arguments[i]];
}
}else if(arguments.length==3){
for(var name in givingClass.prototype){
if(isOverride){
receivingClass.prototype[name]=givingClass.prototype[name];
}else{
//不覆蓋
if(!receivingClass.prototype[name]){
receivingClass.prototype[name]=givingClass.prototype[name];
}
}
}
}else{
throw "Please give 3 arguments at least!";
}
}
2,copyObjectProperties復制對象的屬性
/*
* 把源對象的所有屬性復制到目標對象上,第一個參數是boolean值,表示是否覆蓋目標對象的屬性
*/
function copyObjectProperties(isOverride,receivingObject,givingObject){
if(arguments.length>3){
for(var i=3;i<arguments.length;i++){
receivingObject[arguments[i]]=givingObject[arguments[i]];
}
}else if(arguments.length==3){
for(var name in givingObject){
if(isOverride){
receivingObject[name]=givingObject[name];
}else{
//不覆蓋
if(!receivingObject[name]){
receivingObject[name]=givingObject[name];
}
}
}
}else{
throw "Please give 3 arguments at least!";
}
}
3,copyProperties復制屬性到對象
/*
* 把屬性復制到目標對象中,屬性可以有任意多個,并且可以是數組。
*/
function copyProperties(target){
for (var i=1;i<arguments.length;i++){
if(arguments[i].constructor===Array){
copyArrayProperties(target,arguments[i]);
}else{
for(var name in arguments[i]){
target[name] =arguments[i][name];
}
}
}
}
/*
* 把數組格式的屬性復制到目標對象中,用戶不應該直接調用這個方法
*/
function copyArrayProperties(target,arrayArg){
for(var i=0;i<arrayArg.length;i++){
if(arrayArg[i].constructor===Array){
copyArrayProperties(target,arrayArg[i]);
}else{
for(var name in arrayArg[i]){
target[name] =arrayArg[i][name];
}
}
}
}
PS:目前我正打算寫一個JavaScript庫,用簡潔的代碼提供很多功能,包括UI組件。
JavaScript技術:用JavaScript實現單繼承和多繼承的簡單方法,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。