Home  >  Article  >  Web Front-end  >  js inherits the source code analysis of the Base class_js object-oriented

js inherits the source code analysis of the Base class_js object-oriented

WBOY
WBOYOriginal
2016-05-16 18:56:461003browse

// 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){
//When the parameter is greater than one
if (arguments.length > 1) { // extending with a name/value pair
//Get the ancestor of proto
var ancestor = this[source];
var value = arguments[1] ;
//If value (second parameter) is function and the ancestor object exists, when base is called in the overloaded function
if (typeof value == "function" && ancestor && /bbaseb/.test (value) {
// get the underlying method
var method = value;
// override
value = function(){
var previous = this.base;
this.base = ancestor;
//Trace back to the parent class object
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 Use a list of objects to extend
var extend = Base.prototype.extend;
/**
* 1. Extend prototype methods and properties 2.
*/
//If you are extending a method or property belonging to the prototype, First traverse the three methods of overloaded Object
if (Base._prototyping) {
var key, i = 0, members = ["constructor", "toString", "valueOf"];
while (key = members[i ]) {
//If these methods are overloaded
if (source[key] != Object.prototype[key]) {
/**
* Expand one by one. The reason for using call is to change the context of extend to the source this to be extended.
* is the parent class object of the new object
* /
extend.call(this, key, source[key]);
}
}
}
else
if (typeof this != "function") {
// if the object has a customized 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
/**
* Extended alias of Base class prototype, call this as a method
*/
var extend = Base.prototype.extend;
/**
* build the prototype, create the prototype
* Set the prototype flag
*/
Base._prototyping = true;
/**
* Create an instance of Base and initialize the inheritance part
* The inheritance method is roughly as follows:
* 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);
}
반환
}
});

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn