簡潔明了地用JavaScript實現單繼承和多繼承

來源:互聯網
上載者:User

 

                       簡潔明了地用JavaScript實現單繼承和多繼承

                                         by  沈東良  http://blog.csdn.net/shendl/

 

         JavaScript是一種強大的多泛型程式設計語言,其融合了面向過程、物件導向和函數式編程於一身,具備強大的表現能力。

         JavaScript就其本質是函數式程式設計語言,是Lisp的後代,同時又加入了一下物件導向編程的元素,放棄了一些難懂的函數式語言的元素。

         函數式程式設計語言可以實現物件導向編程,這是毫無疑義的,Curry方法可以實現對類和對象的類比。但是JavaScript提供了另一種實現OOP的方法:原型繼承。

         因此,JavaScript實現物件導向編程和一般的函數式程式設計語言還是有所區別的。

         本文我將會給大家介紹JavaScript實現單繼承和多繼承的方法。

用原型實現單繼承:

         有很多JavaScript庫提供了一些函數協助實現單繼承。但實際上,JavaScript本身就提供了原型繼承的方法。因此,根本不需要提供特定的方法來實現,簡單使用JavaScript代碼就可以實現單繼承。

 

         但是,JavaScript提供的原型繼承方法很容易犯錯,下面我給大家示範一下怎樣簡潔明了地實現原型繼承。

         假設MyB繼承MyA類,那麼,代碼如下:

function MyA(){

    if(MyA.prototype.baseClass!==undefined){

       MyA.prototype.baseClass.apply(this,arguments);

    }

   ……一般代碼

}

 

function MyB(){

    if(MyB.prototype.baseClass!==undefined){

       MyB.prototype.baseClass.apply(this,arguments);

    }

    ……一般代碼

}

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.apply(this,arguments);

    }

    這段代碼尋找原型中的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組件。

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.