js 계승 Base 류 의 소스 코드 분석

// timestamp: Tue, 01 May 2007 19:13:00 /* base2.js - copyright 2007, Dean Edwards http://www.opensource.org/licenses/mit-license */ // You know, writing a javascript library is awfully time consuming. //////////////////// BEGIN: CLOSURE //////////////////// // ========================================================================= // base2/Base.js // ========================================================================= // version 1.1 var Base = function(){ // call this method from any other method to invoke that method's ancestor }; Base.prototype={extend:function(source){/매개 변수 가 하나 이상 일 때 if(arguments.length>1){/extending with a name/value pair//proto 를 얻 은 조상 var ancestor=this[source];var value = arguments[1]; //value(두 번 째 매개 변수)가 function 이 고 조상 대상 이 존재 한다 면,리 셋 함수 에서 base 를 호출 할 때 if(type:of value=="function"&&ancestor&&/\bbase\b/.test(value){/get the underlying method var method=value;/override value = function(){ var previous = this.base; this.base = ancestor; //부모 클래스 대상 var returnValue=method.apply(this,arguments)로 거 슬러 올 라 갑 니 다.this.base = previous; return returnValue; }; value.method = method; value.ancestor = ancestor; } this[source] = value; } else if(source){/extending with an object literal 은 대상 목록 으로 var extend=Base.prototype.extend;/***를 확장 합 니 다.1.원형 확장 방법 과 속성 2.*//원형 확장 방법 이나 속성 이 라면 Object 를 다시 불 러 오 는 3 가지 방법 if(Base.prototyping) { var key, i = 0, members = ["constructor", "toString", "valueOf"]; while(key=members[i++]){//이 방법 들 을 다시 불 러 왔 다 면 if(source[key]!=Object.prototype[key]){/***하나씩 확장 합 니 다.call 을 사용 하 는 이 유 는 extend 의 컨 텍스트 를 확장 할 원본 this 로 바 꾸 기 때 문 입 니 다.*새 대상 의 부모 클래스 대상*/extend.call(this,key,source[key])}}}else if (typeof this != "function") { // if the object has a customised extend() method then use it extend = this.extend || extend; } // copy each of the source object's properties to this object for (key in source) if (!Object.prototype[key]) { extend.call(this, key, source[key]); } } return this; }, base: Base }; Base.extend = function(_instance, _static){/subclass/***Base 류 프로 토 타 입의 확장 별명,이 를 하나의 방법 으로 호출*/var extend=Base.prototype.extend;/*****프로 토 타 입 을 빌 드 하고 프로 토 타 입 만 들 기*프로 토 타 입 로고 설정*/Base.prototyping = true; /** * Base 의 인 스 턴 스 를 만 들 고 계승 부분 을 초기 화 합 니 다*계승 방식 은 대체로 다음 과 같 습 니 다*function A(){}*function B(){*this.b=[];*}*A.prototype=new B();//A.B 를 계승 하 는 모든 속성 과 방법*이러한 계승 방식 에 문제 가 있 을 수 있 습 니 다.B 에서 설명 한 대상(예 를 들 어 b)은 prototype 의 형식*A 로 계승 한 후에 prototype 은 B 중의 대상 을 가리 키 는 인용 만 생 성 합 니 다.즉,*A 모든 인 스 턴 스 는 B 중의 대상(b)*var a1=new A()를 공동으로 누 릴 수 있 습 니 다.*var a2=new A(); * a1.b.push("a11"); * a2.b.push("a21"); * 이때 a1.b=a2.b=["a11","a21"],*Dean Edwards 는 계승 을 실현 할 때 부모 클래스 를 기반 으로 인 스 턴 스 를 만 듭 니 다.*extend 를 이용 하여 이 인 스 턴 스 를 확장 하고 마지막 으로 A.prototype=new B()를 사용 합 니 다.계승 실현*그러나 속성 이 대상 일 때 처리 하지 않 았 습 니 다.*상기 계승 결함 을 피하 지 않 았 습 니 다*/var proto=new this;/***여기 서 proto.extend(instance)대체*/extend.call(proto,instance); /** * 클래스 인 스 턴 스 속성 과 방법의 원형 부분 구조 가 완료 되 었 습 니 다.플래그 위치 삭제*/delete Base.prototyping; /** * 이 곳 에서 저 자 는 어댑터 모드 를 사용 하여 사용자 정의 구조 기로 새로운 클래스 대상 을 생 성 합 니 다*wrapper/adapter:일정한 방법 으로 한 대상 이 다른*대상 에 게 인 터 페 이 스 를 봉인 하거나 권한 을 부여 하여 인터페이스 나 행동 을 변경 합 니 다*//create the wrapper for the constructor function/****구조 기의 인용*/var constructor=proto.constructor;/*******klass 의 Function 대상 을 만 들 고 사용자 정의 구조 기 를 호출 합 니 다.klass 는 파생 된 하위 클래스*두 가지 상황 에서 이 방법 을 호출 합 니 다.*1.클래스 인 스 턴 스 를 만 들 때 이 때 는 원형 구조 단계 가 아니 라 extend 방법*계승 할 때 설정 한 구조 방법*2.extend 방법 으로 하위 클래스 를 파생 시 킬 때-new this*는 다음 글 에서 klass 의 속성 을 모두 얻 었 기 때 문 입 니 다.*그래서 new 가 끝나 면 모든 부모 클래스 를 얻 는 방법 과 속성 이*proto 에 포함 되 어 있 습 니 다.이때 proto 를 바탕 으로 prototype 의 extend 방법*을 사용 하여 이 하위 클래스 의 속성 과 방법 을 proto 에 추가 합 니 다*/var klass=proto.constructor=function(){/**var proto=new this;부모 클래스 의 구조 함 수 를 호출 하여 부모 클래스 의 인 스 턴 스*new this 를 만 든 후 함수 가 하위 클래스 대상 구조 방법*/if(!Base._prototyping){/**구조 함수 에서(constructor)base 방법 을 호출 할 때*base 방법 은 부모 대상 의 구조 함 수 를 호출 합 니 다.이 때 새 겨 집 니 다*이 코드 세그먼트 를 호출 합 니 다.방법 이 실 행 될 수 있 는 조건 은 this. 입 니 다.constructing==true */ if (this._constructing || this.constructor == klass) { // instantiation this._constructing = true; constructor.apply(this, arguments); delete this._constructing; } /** * * 더 이상 아래로 실행 하지 않 습 니 다*/else{/casting var object=arguments[0];if (object != null) { (object.extend || extend).call(object, proto); } return object; } } }; // build the class interface /** * */ for (var i in Base){ klass[i] = this[i]; } /** * 계승 체인 만 들 기*/klass.ancestor=this;klass.base = Base.base; klass.prototype = proto; klass.toString = this.toString; /** * 확장 클래스 방법,속성,자바 와 유사 한 static*/extend.call(klass,static); // class initialisation init 함수 호출 if(type:of klass.init=="function")klass.init()가 존재 하면;return klass; }; // initialise Base = Base.extend({ constructor: function(){ this.extend(arguments[0]); } }, { ancestor: Object, base: Base, implement: function(_interface){ if (typeof _interface == "function") { // if it's a function, call it _interface(this.prototype); } else { // add the interface using the extend() method this.prototype.extend(_interface); } return this; } });

좋은 웹페이지 즐겨찾기