JavaScript拷贝继承法的应用

前面在JavaScript中继承的实现方法 讲了JavaScript中继承的几种实现方法,这段时间正好在看AJS框架,该框架中用到的是“拷贝继承法”,于是自己仿照写了一个简单的“拷贝继承法”的框架,并加了一些具体的注释,但是有的地方不知道怎样去描述,觉得有不妥的地方,待理解更加透彻之后再修改。

附上源代码:

 

     < script language = " JavaScript " >

    
// 拷贝继承法的使用
     // 引擎类EngineClass的作用是完成继承操作
     // 父类ParentClass是引擎类EngineClass的对象
     // 子类ChildClass是调用ParentClass.extend返回的对象。其实,ChildClass就是继承ParentClass的子类



    
// 定义引擎类EngineClass
    EngineClass  =   function (members)
    
{
        
var fn = function()   
        
{
          
if(arguments[0!= 'no_init')    //如果没有必须执行的方法,该函数体可以为空。
          {
             
return this.NeedInit.apply(this, arguments);   //初始化类中必须有NeedInit方法
             //构造函数 改变this.NeedInit函数中的this指针(即函数内部的this)。执行继承该类的this.NeedInit函数
          }

        }

        fn.prototype 
= members;   //将参数中的方法赋给prototype,创建类对象后,就可以用对象来调用相应的方法
        for(var i in EngineClass.prototype)   //将EngineClass的prototype属性赋给类对象
            fn[i] = EngineClass.prototype[i];
        
return fn;
    }


    EngineClass.prototype 
=  
    
{
        extend: 
function(members)   //拷贝继承法  扩展members成员,然后传入到EngineClass类构造函数,返回EngineClass对象
        {
           
var parentmembers = new this('no_init');  
           
//调用构造函数 即EngineClass中的fn() 返回parentClass对象中方法列表对象

           
for(k in members)     //将父类和子类的方法都合并起来,并且形成继承关系
           {
              
var prev = parentmembers[k];  //父类的方法
              var cur = members[k];         //子类的方法
              if (prev && prev != cur && typeof cur == 'function'
              
{
                 cur 
= this.__parentize(cur, prev); 
                 
//如果父类对象中有该方法,则更改子方法中的this指针,让子类中的方法可以调用父类的同名方法
              }

              parentmembers[k] 
= cur; //将子类中的方法加入到父类对象中来(同名则覆盖)
           }

           
return new EngineClass(parentmembers);  //返回类对象(父类和子类的方法都合并起来)
        }
,

        __parentize: 
function(cur, prev) //指定父类同名方法 
        {
           
return function()
           
{
              
this.parent = prev;     //在子类中调用this.parent({});就可以调用父类的同名方法了。
              return cur.apply(this, arguments);  
              
//this代表EngineClass对象(加了parent)这样子类中的方法就调用父类的同名方法了
           }

        }
,

        init: 
function()
        
{
           alert(
'初始化EngineClass后就可以调用我');
        }

    }



    
// 创建基类EngineClass的对象ParentClass(ParentClass对象可以调用extend,init方法) ParentClass相当于基类  
     // 将{init,func2,func3}作为参数赋给EngineClass构造函数的members
    ParentClass  =   new  EngineClass
    (
      
{
         NeedInit: 
function()
         
{
            alert(
'ParentClass父类,该方法必须存在! 我有子类来调用');
         }
,
         ParentClassinit: 
function()
         
{
            alert(
'1、EngineClass做拷贝继承操作 2、必须对象化ChildClass类  才能调用ParentClassinit');
         }

      }

    )


    
// ChildClass将返回ParentClass.extend方法中的返回的对象,如果该方法中为空,则表示返回undefined
     // 所以要要求EngineClass类的extend方法要做一些拷贝方法的操作,来完成继承操作  ChildClass相当于继承ParentClass的子类
     // 调用extend方法,将{func1,func2,func3}作为参数赋给members
    ChildClass  =  ParentClass.extend  
    (
       
{
            NeedInit: 
function()  //创建对象时就调用了。
         {
            alert(
'ChildClass子类,该方法必须存在!创建对象时就调用了,类似构造函数');
            
this.parent({});//调用父类的NeedInit方法
         }
,
         ChildClassinit: 
function()
         
{
            alert(
'1、EngineClass做拷贝继承操作 2、必须对象化ChildClass类  才能调用ChildClassinit');
         }

       }

    )
       

    
var  current  =   new  ChildClass();
    current.ChildClassinit();  
// 类的prototype方法,必须初始化对象后才能调用
    current.ParentClassinit();   // 类的prototype方法,必须初始化对象后才能调用

    ParentClass.init();  
// 不是类的prototype方法,不必初始化对象,可以直接调用
    ChildClass.init();    

    
< / script>

 

 

你可能感兴趣的:(JavaScript)