// 타임스탬프: 2007년 5월 1일 화요일 19:13:00
/*
base2.js - copyright 2007, Dean Edwards
http://www.opensource.org/licenses/mit-license
*/
// 아시다시피 자바스크립트 라이브러리를 작성하는 데 시간이 많이 걸립니다.
//////////////////// BEGIN: CLOSURE // / //////////////////
// ========================== == ============================================
// base2/Base.js
// ===================================== ==== =================================
// 버전 1.1
var Base = function(){
// 다른 메서드에서 이 메서드를 호출하여 해당 메서드의 조상을 호출합니다.
}
Base.prototype = {
extend: function(source){
//When 매개변수가 1보다 큼
if (arguments.length > 1) { // 이름/값 쌍으로 확장
//proto의 조상 가져오기
var 조상 = this[source]; >var value = 인수[1] ;
//값(두 번째 매개변수)이 함수이고 조상 객체가 존재하는 경우 오버로드된 함수에서 base가 호출될 때
if (typeof value == "function" && Ancestral && /bbaseb/.test (value) {
// 기본 메서드 가져오기
var method = value
// override
value = function(){
var Previous = this. base;
this.base = 조상;//상위 클래스 객체로 역추적
var returnValue = method.apply(this, 인수)
this.base = 이전; returnValue;
} ;
value.ancestor = 조상
}
this[source] = value; >if (소스) { / / 객체 리터럴로 확장 확장하려면 객체 목록을 사용하세요.
var extend = Base.prototype.extend;
/**
* 1. 프로토타입 메서드 및 속성 확장 2.
*/
//If 프로토타입에 속하는 메서드나 속성을 확장하는 경우 먼저 오버로드된 Object의 세 가지 메서드를 순회합니다.
if (Base._prototyping) {
var key, i = 0,members = ["constructor", "toString", "valueOf"];
while (key =members[i ]) {
//이 메서드가 오버로드된 경우
if (source[key] != Object.prototype[key]) {
/**
* 하나씩 확장하는 이유는 확장할 소스로 확장 컨텍스트를 변경하기 위해서입니다.
*는 새 개체의 상위 클래스 개체입니다.
* /
extend.call(this, key, source[key])
}
}
}
else
if (typeof this != "function") {
// 객체에 사용자 정의된 확장() 메소드가 있는 경우 이를 사용하세요.
extend = this.extend || 이 객체에 대한 속성
for (key in source)
if (!Object.prototype[key]) {
extend.call(this, key, source[key])
}
}
return this ;
},
base: Base
}
Base.extend = function(_instance, _static){ // 하위 클래스
/**
* Base 클래스 프로토타입의 확장 별칭, 이를 메서드로 호출
*/
var extend = Base.prototype.extend;
/**
* 프로토타입 제작, 프로토타입 생성
* 프로토타입 플래그 설정
*/
Base._prototyping = true;
/**
* Base 인스턴스를 생성하고 상속 부분 초기화
* 상속 방법은 대략 다음과 같습니다.
* function A(){}
* function B(){
* this.b=[]
* }
* A.prototype=new B();//A는 B의 모든 속성과 메서드를 상속합니다.
* 이 상속 메서드에 문제가 있습니다. B에서 선언된 객체(예: b)는 다음과 같은 형식입니다. 프로토타입
* A에 의해 상속된 후 프로토타입은 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"],
* 여기서는
대신 proto.extend(_instance)를 사용할 수 없습니다.* Dean Edwards가 상속을 구현할 때 상위 클래스를 기반으로 인스턴스를 생성하고,
* 확장을 사용하여 인스턴스를 확장하고 마지막으로 A를 사용합니다. 프로토타입=new B(); 상속을 구현합니다
* 그러나 객체인 경우 속성을 처리하지 않습니다
* 여전히 위의 상속 결함을 피하지 않습니다
*/
var proto=new this
/**
* 클래스 인스턴스 속성 및 메소드의 프로토타입 부분이 구성되고 플래그 비트가 삭제됩니다.
*/
extend.call(proto, _instance)
/**
* 여기서 작성자는 어댑터 패턴을 사용하고 사용자 정의 생성자를 사용하여 새 클래스 객체를 생성합니다.
* 래퍼/어댑터: 특정 메서드를 통해 한 객체가 다른
* 객체를 캡슐화하거나 권한을 부여하여 인터페이스를 변경합니다. 또는 행동
*/
delete Base._prototyping ;
/**
* 생성자에 대한 참조 가져오기
*/
// 생성자 함수에 대한 래퍼 생성
/**
* klass의 Function 객체를 생성하고 사용자 정의 생성자를 호출합니다. klass는 파생 하위 클래스입니다.
* 두 가지 경우에 이 메서드를 호출합니다.
* 1. 클래스 인스턴스를 생성할 때 이때는 프로토타입 구축 단계가 아니고, 상속시 상속 메소드
* 에서 설정한 구축 메소드가 실행됩니다
* 2. 서브 클래스 파생을 위해 확장 메소드를 사용할 경우---new this
* klass 때문에 아래의 모든 속성을 얻었으므로
* new가 완료된 후에는 상위 클래스의 모든 메소드와 속성이
* proto에 포함됩니다. 이때 proto를 기반으로 프로토타입의 확장 메소드를 사용합니다.
* proto에 이 하위 클래스의 속성과 메서드를 추가하세요
*/
var constructor = proto.constructor
/* *
* var proto=new this; 상위 클래스의 생성자를 호출하고 상위 클래스의 인스턴스를 생성합니다.
* new this를 모두 사용한 후 함수는 하위 클래스 객체 생성 메서드로 리디렉션됩니다.
*/
var klass = proto.constructor = function(){
/**
* 생성자에서 기본 메서드가 호출되면
* 기본 메서드는 상위 클래스 개체의 생성자를 호출합니다. 이때
* 호출 이 코드 세그먼트가 중첩되고 메소드가 실행됩니다. 조건은 this._constructing==true
*/
if (!Base._prototyping) {
/**
*
*는 더 이상 하향 실행되지 않습니다.
*/
if (this._constructing || this.constructor == klass) { // 인스턴스화
this._constructing = true;
constructor.apply(this, 인수)
delete this ._constructing;
}
/**
*
*/
else { // 캐스팅
var object = 인수[0]
if (object != null) {
(object.extend || 확장) call(object, proto);
}
return object;
}
}// 클래스 인터페이스 구축
/**
* 상속 체인 생성
*/
for (var i in Base){
klass[i] = this[i]
}
/**
* Java의 정적 메소드와 유사한 클래스 메소드, 속성 확장
*/
klass.ancestor = this;
klass.base = Base.base;
klass.prototype = proto;
klass.toString =
/***/
extend.call(klass, _static );
// 클래스 초기화 init 함수 호출이 있는 경우
if (typeof klass.init == "function")
klass.init();
return klass;
};
// 초기화
Base = Base.extend({
constructor: function(){
this.extend(arguments[0]);
}
}, {
조상: 객체,
베이스: 베이스,
구현: function(_interface){
if (typeof _interface == "function") {
// 함수라면 호출하세요
_interface(this.prototype);
}
else {
// 확장() 메서드를 사용하여 인터페이스를 추가하세요
this.prototype.extend (_interface);
}
반환
}
});