ExtJS 에서 계승 하 는 실현 과 이해 - extend

다음은 네트워크 상의 자원 을 참고 한다.
 
Ext 에서 클래스 의 계승 실현
extend (Object subclass,Object superclass,[Object overrides] : Object)

  첫 번 째 매개 변수: 하위 클래스 두 번 째 매개 변수: 부모 클래스 세 번 째 매개 변수: 덮어 쓸 속성.하위 클래스 는 부모 클래스 에서 슈퍼 클래스. prototype 방식 으로 정 의 된 속성 (이 방법 으로 정 의 된 함수 포함) 을 계승 하고 슈퍼 클래스 에서 정 의 된 속성 과 방법 을 계승 하지 않 으 며, 하위 클래스 의 방법 명 이 부모 클래스 와 같 으 면 덮어 씁 니 다.예시
    부계
BaseClass = function() {
 f1 = function() {
  alert("f1 in base");
 },
 f2 = function() {
  alert("f2 in base");
 }
}
BaseClass.prototype = {
 f3 : function() {
  alert("f3 in base");
 },
 f4 : function() {
  alert("f4 in base");
 }
};

      하위 클래스
ChildClass = function() {
}
//   
Ext.extend(ChildClass, BaseClass, {
   f1 : function() {
    alert("f1 in child");
   },
   f3 : function() {
    alert("f3 in child");
   }
  });

      실례 화
var b = new ChildClass();
b.f1();//         
//b.f2();//    ,          ,        f2     ,          (  )
b.f3();//      ,         
b.f4();//   ,         

 
     보충: JavaScript 의 원형 계승 에 대한 이 해 를 통 해 알 수 있 듯 이 인 스 턴 스 변수의 우선 순 위 는 prototype 보다 높 습 니 다. 제 가 전에 쓴 글 javascript 에서 정적 방법, 인 스 턴 스 방법, 내부 방법 과 원형 에 대한 약간의 견해 을 참조 하 십시오.    부계
BaseClass = function() {
 this.f1 = function() {
  alert("f1 in base");
 },
 this.f2 = function() {
  alert("f2 in base");
 }
}

      하위 클래스
ChildClass = function() {
 ChildClass.superclass.constructor.call( this ); 
}
//   
Ext.extend(ChildClass, BaseClass, {
   f1 : function() {
    alert("f1 in child");
   },
   f3 : function() {
    alert("f3 in child");
   }
  });

      실례 화
var b = new ChildClass();
b.f1();//         ,            
b.f2();//         
b.f3();//         

 
    분석: ChildClass. superclass. constructor. call (this) 에서;이 문장 에서 BaseClass 의 f1 은 ChildClass 의 변수 가 되 었 고 ChildClass. prototype 이 아니다.인 스 턴 스 변수의 우선 순 위 는 prototype 보다 높 기 때문에 위의 이 코드 는 override 기능 에 이 르 지 못 합 니 다.
    상기 지식 을 알 게 되 었 습 니 다. 다음은 extend 의 실현 을 설명 하 겠 습 니 다. 먼저 가장 간단 한 계승, 실현 원 리 를 보 겠 습 니 다.하위 클래스 에 하위 클래스 의 원형 을 부여 하 는 구조 기 다.    다음 코드 는 subfn 의 prototype 을 슈퍼 fn 의 인 스 턴 스 로 설정 한 다음 subfn. prototype. constructor 를 subfn 으로 설정 합 니 다.
function Extend(subFn, superFn) {
 subFn.prototype = new superFn();
 subFn.prototype.constructor = subFn;
}

//  
function Animal() {
 this.say1 = function() {
  alert("Animal");
 }
}
//  
function Tiger() {
 this.say2 = function() {
  alert("Tiger");
 }

}
//    
Extend(Tiger, Animal);
var tiger = new Tiger();
tiger.say1();// "Animal"
tiger.say2();// "Tiger"


 
     가장 간단 한 계승 은 두 가지 일 만 한 것 을 볼 수 있 습 니 다. 하 나 는 subfn 의 prototype 을 슈퍼 fn 의 인 스 턴 스 로 설정 한 다음 subfn, prototype, constructor 를 subfn 으로 설정 합 니 다.
Ext. extend 코드
     Ext. extend 함수 에 Ext. override 를 사 용 했 습 니 다. 이 함 수 는 두 번 째 매개 변수 중의 모든 대상 을 첫 번 째 대상 의 prototype 에 복사 합 니 다.우선 Ext. override 함수 의 코드 를 붙 입 니 다.
/**
         * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
         * Usage:<pre><code>
Ext.override(MyClass, {
    newMethod1: function(){
        // etc.
    },
    newMethod2: function(foo){
        // etc.
    }
});
</code></pre>
         * @param {Object} origclass The class to override
         * @param {Object} overrides The list of functions to add to origClass.  This should be specified as an object literal
         * containing one or more methods.
         * @method override
         */
        override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;
                Ext.apply(p, overrides);
                if(Ext.isIE && overrides.hasOwnProperty('toString')){
                    p.toString = overrides.toString;
                }
            }
        }


 
    다음은 Ext. extend 코드 입 니 다.
/** 
  *   ,                   
  *            override()   ,          
  * @param { Object } subclass   ,    (           ,        ) 
  * @param { Object } superclass   ,    
  * @param { Object } overrides (     )     ,                 
  * @method extend 
  */ 
        extend : function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;

            //      
            //    sb、sp、overrides    subClass(  )、superClass(  )          
            return function(sb, sp, overrides){
                if(typeof sp == 'object'){//       superClass, overrides
                    overrides = sp;
                    sp = sb;
                    sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
                }
                var F = function(){},//      ,             
                    sbp,
                    spp = sp.prototype;

                F.prototype = spp;
                //         JavaScript         。
                sbp = sb.prototype = new F();//  
                sbp.constructor=sb;
                //     superclass      superclass   prototype
                sb.superclass=spp;
                if(spp.constructor == oc){
                    spp.constructor=sp;
                }
                //   subClass   subClassPrototype    override   
                sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.superclass = sbp.supr = (function(){
                    return spp;
                });
                sbp.override = io;
                //       prototype     
                Ext.override(sb, overrides);
                //        :extend
                sb.extend = function(o){return Ext.extend(sb, o);};
                return sb;
            };
        }(),


 
    코드 에 너무 많은 약 자 를 했 습 니 다. 보기에 특별히 편리 하지 않 습 니 다. 코드 에 있 는 약 자 를 보완 하 세 요. 코드 는 다음 과 같 습 니 다.
extend : function(){
            // inline overrides
            var inlineOverride = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;

            return function(subFn, superFn, overrides){
                if(typeof superFn == 'object'){
                 //    superFn       (     superFn             ),        overrides          
                    overrides = superFn;
                    superFn = subFn;
                    //        subFn 
                    subFn = overrides.constructor != oc ? overrides.constructor : function(){superFn.apply(this, arguments);};
                }
                var F = function(){},
                    subFnPrototype,
                    superFnPrototype = superFn.prototype;

                F.prototype = superFnPrototype;
                subFnPrototype = subFn.prototype = new F();
                subFnPrototype.constructor=subFn;
                subFn.superclass=superFnPrototype;
                if(superFnPrototype.constructor == oc){
                    superFnPrototype.constructor=superFn;
                }
                subFn.override = function(o){
                    Ext.override(subFn, o);
                };
                subFnPrototype.superclass = subFnPrototype.supr = (function(){
                    return superFnPrototype;
                });
                subFnPrototype.override = inlineOverride;
                Ext.override(subFn, overrides);
                subFn.extend = function(o){return Ext.extend(subFn, o);};
                return subFn;
            };
        }()


 
     코드 에 두 개의 매개 변수 와 세 개의 매개 변수의 실현 이 섞 여 있어 이해 하기 가 쉽 지 않다. 우 리 는 코드 를 두 개의 매개 변수 와 세 개의 매개 변수의 실현 으로 나 눌 수 있다. 다음 과 같은 두 매개 변수의 Ext. extend 코드 이다.
 
function extend() {
 // inline overrides
 var inlineOverride = function(o) {
  for (var m in o) {
   this[m] = o[m];
  }
 };
 return function(superFn, overrides) {
  //        
  var subFn=overrides.constructor != Object.prototype.constructor ? overrides.constructor : function(){superFn.apply(this, arguments);};
  //       ,      
  var F = function() {

  }, subFnPrototype, superFnPrototype = superFn.prototype;

  F.prototype = superFnPrototype;//F       superFn.prototype     

  //         JavaScript         。
  subFnPrototype = subFn.prototype = new F();
  subFnPrototype.constructor = subFn;
  //          constructor,           
  if(superFnPrototype.constructor == oc){
        superFnPrototype.constructor=superFn;
  }
  //     superclass      superFn   prototype
  subFn.superclass = superFnPrototype;

  //   subFn   subFnPrototype    override   
  subFn.override = function(obj) {
   Ext.override(subFn, obj);
  };
  subFnPrototype.override = inlineOverride;
  
  //       prototype     
  Ext.override(subFn, overrides);
  //        :extend
  subFn.extend=function(o){
   Ext.extend(subFn,o);
  }
  return subFn;
 };

};


 
     주석 에서 볼 수 있 듯 이 하 는 일 은 매우 간단 합 니 다. subFn 함수 만 정의 할 뿐 이 함수 에 서 는 슈퍼 Fn 함수 가 호출 됩 니 다.subfn 을 정의 한 후 위의 가장 간단 한 계승 방식 으로 계승 을 실현 합 니 다.그리고 subfn 과 subfn 의 prototype 에 override 함 수 를 추가 합 니 다.마지막 Ext. override (subfn, overrides);overrides 의 함 수 를 subfn 의 prototype 에 기록 합 니 다.
     다음은 두 개의 매개 변 수 를 전달 하 는 간단 한 예 이다.
 
	var BaseClass = function(){};
	BaseClass.prototype = {
		method1 : function(){
			alert('father class');
		}
	};
	//       
	var subClass = Ext.extend(BaseClass,{
		method2 : function(){
			alert('sub class');
		}
	});
	
	var sub = new subClass();
	sub.method1();
	sub.method2();
 
    세 매개 변수의 Ext. extend 코드
function extend() {
 // inline overrides
 var inlineOverride = function(o) {
  for (var m in o) {
   this[m] = o[m];
  }
 };
 return function(subFn, superFn, overrides) {
        //        ,      
  var F = function() {

  }, subFnPrototype, superFnPrototype = superFn.prototype;

  F.prototype = superFnPrototype;// F       superFn.prototype     

  //         JavaScript         。
  subFnPrototype = subFn.prototype = new F();
  subFnPrototype.constructor = subFn;

  //     superclass      superFn   Prototype
  subFn.superclass = superFnPrototype;
  //          constructor,           
  if(superFnPrototype.constructor == oc){
        superFnPrototype.constructor=superFn;
  } 
  //   subFn   subFnPrototype    override   
  subFn.override = function(obj) {
   Ext.override(subFn, obj);
  };
  subFnPrototype.override = inlineOverride;
  //       prototype     
  Ext.override(subFn, overrides);
  //         :extend
  subFn.extend = function(o) {
   Ext.extend(subFn, o);
  }
  return subFn;
 };
};

        프로 세 스 는 두 개의 매개 변수 와 차이 가 많 지 않 습 니 다. 단지 두 개의 매개 변수 일 때 subfn 에서 다시 정의 하 는 function 이 고 세 개의 매개 변수 일 때 이 절 차 는 생략 됩 니 다.
 
      다음은 세 개의 매개 변 수 를 전달 하 는 예 이다.
	var BaseClass = function(){};
	BaseClass.prototype = {
	    method1 : function(){
		alert('father class');
	    }
	};
	
	//       
	var subClass = function(){}
	Ext.extend(subClass,BaseClass,{
	   method2 : function(){
		alert('sub class');
	   }
	});
	
	var sub = new subClass();
	sub.method1();
	sub.method2();
 
      이렇게 하면 여러분 은 이 함수 에 대해 잘 아 시 겠 죠? Ext. extend 의 계승 은 구조 함수 prototype 의 대상 만 덮어 쓰 는 것 을 알 수 있 습 니 다. 사용 할 때 더욱 주의해 야 합 니 다.

좋은 웹페이지 즐겨찾기