>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 객체지향 패키징 클래스 분석 클래스 패키징 클래스 library_javascript 기술

자바스크립트 객체지향 패키징 클래스 분석 클래스 패키징 클래스 library_javascript 기술

WBOY
WBOY원래의
2016-05-16 17:42:591486검색

JavaScript는 진입 장벽이 매우 낮은 언어입니다. JavaScript를 접해본 적이 없는 기술자라도 몇 시간 안에 간단하고 유용한 프로그램 코드를 작성할 수 있습니다.

그러나 결론적으로 말하면 JavaScript는 간단한 언어입니다. 그렇다면 당신은 완전히 틀렸습니다. 고성능 코드를 작성하려면 수석 프로그래머의 기본 자질도 갖춰야 합니다.

Java나 C 프로그래머가 꼭 고성능 자바스크립트 코드를 작성할 수 있는 것은 아니지만, 고성능 자바스크립트 코드를 작성하는 것이 더 쉽습니다.
JavaScript의 단순성은 "광범위한" 포괄성에 기반을 두고 있습니다. 선언되면 유형을 지정할 필요가 없으며 어떤 유형으로든 변환할 수도 있습니다. 객체 지향적이지만 클래스에 제한이 없습니다. 자유를 옹호하고 매우 엄격한 언어입니다. 자유주의자라면 JavaScript를 받아들이세요!

객체 지향 프로그래밍(OOP)은 인기 있는 프로그래밍 방법입니다. 그러나 JavaScript의 OOP는 JAVA 및 C와 매우 다르며 주로 다른 상속 방법을 반영합니다. JavaScript는 프로토타입 PROTOTYPE을 기반으로 상속됩니다. 모든 객체는 궁극적으로 Object 객체로 추적되는 프로토타입 체인을 기반으로 합니다.

자바스크립트의 상속 방식과 다른 언어의 상속 방식의 차이점에 대해서는 별로 이야기하고 싶지 않습니다. 기본 코드를 더 잘 관리 및 유지하고, 중복 코드를 줄이고, 더 나은 모듈식 프로그래밍을 달성하기 위해 JavaScript 클래스를 캡슐화하는 방법을 주로 논의합니다.

다음은 github에서 찾을 수 있는 더 나은 클래스 캡슐화 라이브러리 중 일부입니다:
1 MY-CLASS
프로젝트 주소: https://github.com/jiem/ my-class
먼저 기본 사용법을 살펴보겠습니다.
a. 새 클래스 만들기

코드 복사 코드는 다음과 같습니다.

(function(){
//New class
varPerson=my.Class({
//정적 메서드 추가
STATIC: {
AGE_OF_MAJORITY: 18
},
//생성자
constructor:function(name,age){
this.name=name;
this.age=age; >},
//인스턴스 메소드
sayHello:function(){
console.log('Hellofrom' this.name '!')
},
//인스턴스 메소드
drinkAlcohol:function (){
this.ageconsole.log('Tooyoung!Drinkmilkinstead!'):
console.log('Whiskeyorbeer?'); }
} );
//네임스페이스
myLib.Person=Person;
})()
varjohn=newmyLib.Person('John',16); >john.sayHello ();//log"HellofromJohn!"
john.drinkAlcohol();//log"Tooyoung!Drinkmilkinstead!"


b. 🎜>

코드 복사
코드는 다음과 같습니다. (function(){ //Dreamer는 Person을 상속받습니다. varDreamer=my.Class(Person,{
//생성자 메서드
constructor:function(name,age,dream){
Dreamer.Super.call(this,name,age);
this.dream=dream ;
},
//인스턴스 메소드
sayHello:function(){
superSayHello.call(this)
console.log('Idreamof' this .dream '!');
},
//인스턴스 메소드
wakeUp:function(){
console.log('Wakeup!')
}
}) ;
//Super 상위 클래스에 액세스
varsuperSayHello=Dreamer.Super.prototype.sayHello
//전역 네임스페이스에 노출
myLib.Dreamer
})() ;
varsylvester=newmyLib.Dreamer('Sylvester',30,'eatingTweety');
sylvester.sayHello();//log"HellofromSylvester!IdreamofeatingTweety!" log"Wakeup!"


c. 클래스에 새 메소드 추가



코드 복사

코드는 다음과 같습니다. //myLib.Dreamer에 새 메서드 추가my.extendClass(myLib.Dreamer,{ //정적 메서드 추가STATIC:{
s_dongSomeThing:function(){
console.log("dosomething!")
}
},
//인스턴스 메소드 추가
touchTheSky:function(){
console.log('Touchingthesky');
} ,
//인스턴스 메소드 추가
reachTheStars:function(){
console.log('Sheissopretty!')
});


d. 클래스 메소드 구현




코드 복사


다음:

//새 클래스 선언
myLib.ImaginaryTraveler=my.Class({
travel:function(){console.log('Travelingonacarpet!');},
crossOceans: function(){console.log('SayinghitoMobyDick!');}
});
(function(){
//Dreamer는 Person의 ImaginaryTraveler 구현 방법을 상속합니다.
varDreamer=my.Class( Person,ImaginaryTraveler,{
//생성자 메서드
constructor:function(name,age,dream){
Dreamer.Super.call(this,name,age)
this.dream=dream; ;
}
//...
});
//전역 네임스페이스
myLib.Dreamer=Dreamer
})(); =newDreamer('Aladdin');
aladdininstanceofPerson;//true
aladdininstanceofImaginaryTraveler;//false
aladdin.travel();
aladdin.wakeUp(); ;


새 연산자를 잊어버릴까봐


varPerson=my.Class({
//이제 new
없이 생성자를 호출할 수 있습니다
constructor:function(name,city){
if(!(thisinstanceofPerson))
returnnewPerson (이름,도시);
this.name=name;
}
})


소스를 살펴보겠습니다. my.class의 코드 분석:
my.Class의 구현 아이디어는 기본적으로 다음과 같습니다. 매개변수가 하나만 있으면 기본 클래스가 선언되어 메소드, 속성 및 생성자를 선언합니다. 새로운 수업의. 상속되지는 않지만 상속될 수 있습니다.

상속의 개념은 매개변수가 2개일 경우 첫 번째 매개변수는 상위 클래스로 상속되고, 두 번째 매개변수는 새 클래스의 메소드, 속성, 생성자를 선언하는 데 사용된다는 것입니다. 상속받을 수도 있습니다.

상속된 상위 클래스인 첫 번째 매개변수를 제외하고 매개변수가 3개 이상인 경우 마지막 매개변수를 사용하여 새 클래스의 메서드, 속성, 생성자를 선언합니다. 중간 매개변수는 클래스를 사용하여 새 클래스를 확장하는 메서드입니다. 물론 my.extendClass를 통해 새로운 메서드를 확장할 수도 있습니다.
동시에 클래스 라이브러리는 commonJS와 브라우징 환경을 모두 지원합니다!


코드 복사 코드는 다음과 같습니다.

/*globalsdefine:true,window:true,module:true*/
(function(){
//Namespaceobject
varmy={};
//AMD 보장 하위 모듈을 사용할 수 있습니다
if(typeofdefine!=='undefine')
define([],function(){
returnmy;
})
elseif(typeofwindow!== '정의되지 않음')
//클라이언트를 사용할 수 있는지 확인
window.my=my;
else
//배경을 사용할 수 있는지 확인
module.exports=my; >//==== ========================================== ======= ======================
//@methodmy.Class
//@paramsbody:Object
//@paramsSuperClass:function, ImplementClasses:function...,body:Object
//@returnfunction
my.Class=function(){
varlen=arguments.length
varbody=arguments; [len-1];/ /마지막 매개변수는 자신을 지정하는 메서드입니다
varSuperClass=len>1?arguments[0]:null;//첫 번째 매개변수는 상속된 메서드(인스턴스와 정적 모두)를 참조합니다. 부분은 상속됨
varhasImplementClasses=len> 2;//세 번째 매개변수가 있는 경우 두 번째 매개변수는 실제로 인스턴스 객체인
varClass, SuperClassEmpty
만 상속하는 구현 클래스입니다.//보장된 생성자 메서드
if(body.constructor=== Object){
Class=function(){};
}else{
Class=body.constructor; 나중에 덮어쓰지 않음
deletebody.constructor;
}
//superClass 부분 처리
if(SuperClass){
//미들웨어는 인스턴스 속성 상속을 구현합니다
SuperClassEmpty=function() {};
SuperClassEmpty.prototype=SuperClass.prototype;
Class.prototype=newSuperClassEmpty();//프로토타입 상속, 역참조
Class.prototype.constructor=Class;//보장된 생성자
클래스 .Super=SuperClass;//상위 객체 액세스 인터페이스
//정적 메소드 상속, superClass 메소드 오버로드
extend(Class,SuperClass,false)
}
//ImplementClass 부분 처리, 실제로 SuperClass#arguments[0] #And body#arguments[length-1]#
if(hasImplementClasses)
for(vari=1;i//implement는 상속된 인스턴스 속성 부분, 오버로드된 상위 객체 ImplementClass 메소드
extend(Class.prototype,arguments[i].prototype,false)
//처리 자체가 본문 부분을 선언합니다. , 정적 부분은 STATIC으로 지정되어야 하며 인스턴스 부분은 STATIC 부분을 삭제해야 합니다.
extendClass( Class,body)
returnClass
///===== ========================= ========================= =====================
/ /@methodmy.extendClass
//@paramsClass:function,extension:Object,?override:boolean=true
varextendClass=my.extendClass=function(Class,extension,override){
//정적 부분 정적 부분 상속
if(extension.STATIC){
extend(Class,extension.STATIC, override);//인스턴스 부분이 정적 메서드를 상속하지 않도록 보장
deleteextension.STATIC;
}
//인스턴스 속성은 인스턴스 부분에서 상속됩니다.
extend(Class. 프로토타입, 확장, 재정의)
//=============== =============== =============================================
varextend=함수 (obj,extension,override){
varprop;
//사실 여기의 flase는 상위 객체를 재정의하는 방법을 나타냅니다.
if(override===false){
for(propinextension )
if(!(propinobj))
obj[prop]=extension[prop];
}else{
// 실제로 여기에서는 다음을 포함하여 상위 개체의 메서드를 다루지 않습니다. toString
for(propinextension)
obj[prop]=extension[prop];
if(extension.toString!==Object.prototype.toString)
obj.toString=extension.toString; 🎜>}
};
})();



2. KLASS

프로젝트 주소: https://github.com/ded/ klass
사용 방법을 먼저 살펴보겠습니다.
a. 새 클래스 만들기


코드 복사

.statics({ //정적 메서드
head:':)',
feet:'_|_'
})
.methods({//인스턴스 메서드
walk:function() {}
})


b. 클래스 상속



코드 복사

코드는 다음과 같습니다. : //SuperHuman은 Person을 상속합니다 varSuperHuman=Person.extend(function(name){ //부모 클래스의 생성자를 자동으로 호출합니다 })
.methods ({
walk:function(){
//부모 클래스
this.supr()
this.fly()
}의 walk 메서드를 호출하도록 명시적으로 선언합니다.
fly :function(){}
})
newSuperHuman('Zelda').walk()


c, 리터럴 모드에서 클래스 선언



코드 복사

코드는 다음과 같습니다. varFoo=klass({ foo:0, initialize :function(){ this.foo=1
},
getFoo:function(){
returnthis.foo
},
setFoo:function(x){
this.foo= x
returnthis.getFoo()
}
})


d. 클래스 메서드 구현
때때로 인스턴스 메서드를 재정의하거나 혼합하고 싶을 수 있으므로 다음과 같이 할 수 있습니다.
코드 복사 코드는 다음과 같습니다.

//리터럴을 전달하여
varAlien=SuperHuman.extend({
beam:function(){ this .supr()
//beamintospace
}
})
varSpazoid=newAlien('Zoopo')
if(beamIsDown){
//빔 방법 재정의
Spazoid.implement({
beam:function(){
this.supr()
//fallbacktojets
this.jets()
}
})
}


klass 소스 코드 분석을 살펴보겠습니다: klass의 기본 디자인 아이디어는 매우 명확하며 상속을 모방하기 위해 최선을 다합니다. 다른 언어의 방법. 예를 들어, 하위 클래스 생성자는 상위 클래스의 생성자를 호출하며, 상위 클래스의 메서드를 호출하도록 명시적으로 선언할 수도 있습니다.

이런 종류의 판단은 정규 매칭을 기반으로 합니다: fnTest=/xyz/.test(function(){xyz;})?/bsuprb/:/.*/; 키워드 "super"
상위 클래스의 메소드가 호출된다는 것을 명시적으로 선언합니다. 메소드가 선언되면 내부적으로 상위 클래스의 메소드를 호출하고 현재 클래스의 메소드에 동일한 값을 반환하는 함수로 패키징됩니다.

반면에 구축 방식도 비교적 유연합니다. 초기화가 명시적으로 선언된 경우 이는 생성자입니다. 그렇지 않고 매개변수가 함수이면 생성자로 사용되고, 그렇지 않으면 상위 클래스의 생성자가 사용됩니다.

정적을 통해 정적 메서드를 추가하고, 인스턴스의 구현 및 정적 메서드 메서드를 통해 인스턴스 메서드를 추가합니다.
상속은 상위 클래스의 확장을 통해 이루어집니다.
동시에 클래스 라이브러리는 commonJS와 브라우징 환경을 모두 지원합니다!

코드 복사 코드는 다음과 같습니다.

/**
*Klass.js-copyright@dedfat
*version1.0
*https://github.com/ded/klass
*Followoursoftwarehttp://twitter.com/dedfat:)
*MIT라이센스
*/
!function(context,f){
//fnTest는 상위 상위 클래스 메서드 호출 방법을 알아내는 것이 가능한지 확인하는 데 사용됩니다. 정규식을 통해
varfnTest=/xyz/.test(function(){xyz;})?/bsuprb/:/.*/,
noop=function(){},
proto='prototype ',
isFn =function(o){
returntypeofo===f;
}
//기본 클래스
functionklass(o){
returnextend.call(typeofo= =f?o:noop ,o,1)
}
//동일한 이름의 슈퍼 메소드를 차용하는 함수로 래핑
functionwrap(k,fn,supr){
returnfunction(){
//원본 this.super 캐시
vartmp=this.supr;
//this.super를 임시로 변경하여 super 위의 동일한 이름의 메소드를 차용합니다
// o에 명시적 문 제공(fnTest.text(fn)= =true) 동일한 이름의 슈퍼 메서드를 빌리려면
this.supr=supr[proto][k]
//Borrow 실행을 사용합니다. 반환 값을 저장합니다
varret=fn.apply(this,arguments);
//원래 this.super를 복원합니다.
this.supr=tmp>//반환 값을 반환하여 래핑 후 반환 값이 원래
returnret
}
}
//o와 super에 동일한 이름의 메서드가 있고 o가 명시적으로 다음 메서드를 차용한다고 선언한 경우 super에서 같은 이름의 메서드를 사용하기 위해 실행되도록 함수에 래핑합니다
//super에서 같은 이름의 메서드를 빌리라는 명시적인 선언이 없거나 o의 고유한 메서드이거나 메소드가 아니면 그냥
functionprocess(what,o,supr){
for(varkino){
을 사용하세요.//상속되지 않는 메소드라면 메소드 주석 규칙에 따라 실행하세요. 마지막으로 what
if(o.hasOwnProperty(k)){
what[k]=typeofo[k]==f
&&typeofsupr[proto][k]==f
&&fnTest에 넣습니다. test(o[k])
?wrap(k,o[k],supr):o[k];
}
}
}
//상속된 메서드 구현, fromSub 위의 클래스에서 fromSub는 1이며, 이는 생성자가
functionextend(o, fromSub){
//noop를 실행하는 데 super를 사용하지 않음을 나타냅니다. 미디어 클래스는 프로토타입 상속의 역참조를 구현합니다
noop[proto]=this[proto];
varsupr=this,
prototype=newnoop(),//프로토타입 상속을 위한 인스턴스 객체 생성, 역참조
isFunction=typeofo==f,
_constructor=isFunction?o:this,//o가 생성 메서드인 경우 이를 사용하고, 그렇지 않으면 생성자를 결정합니다.
_methods=isFunction?{}:o, //If o는 {...}이며 fn 프로토타입에 넣으려면 메서드를 사용해야 합니다. 거기에 초기화가 있으면 생성자입니다. o가 함수인 경우 o는 a입니다. constructor
fn=function() {//kclass는 kclass에 의존하기 때문에 결국 실제로 반환되는 것은 fn입니다. 이는 실제로 새 클래스의 생성자입니다.
//1 o가 {... }, 메소드에 의해 직접 필터링되어 fn에 추가됩니다. o의 프로토타입에서 o에 초기화가 있으면 fn의 프로토타입에 초기화가 있으면 생성자 메소드입니다
//2 If o 는 함수이고 메서드는 fn의 프로토타입에 아무것도 추가할 수 없지만 _constructor는 o를 생성자로 허용합니다
//3 o가 {....}이고 초기화가 없으면 이것이 생성자입니다. . klass의 호출에 의해 결정되는 경우 생성자는 분명히 noop입니다. 기본이 아닌 클래스에서 생성자는 상위 클래스의 생성자입니다.
//o는 함수가 아니므로 상위 클래스의 생성자입니다. 클래스는 자동으로 호출되지 않지만 상위 클래스의 생성자는 현재 클래스의 생성자로 간주됩니다.---this 모두 this
console.log(this); if(this.initialize){
this.initialize.apply(this,arguments);
}else{
//상위 클래스 생성자 호출
//위의 3과 같이 o는 함수가 아니며 부모 클래스 생성자가 호출되지 않습니다
//기본 클래스에 부모 클래스가 없으며 부모 클래스 생성자가 호출되지 않습니다
Sub | .apply(this,arguments);
}
};
//프로토타입 메서드 인터페이스 구성
fn.methods=function(o){
process(prototype,o,supr);
fn[proto]=prototype;
returnthis;
}
//새 클래스의 프로토타입을 실행하고 새 클래스의 생성자를 확인합니다.
fn ,_methods).prototype.constructor=fn;
//새 클래스가 상속될 수 있는지 확인
fn.extend=arguments.callee;
//인스턴스 메서드 또는 정적 메서드 추가, statics: 정적 메서드, 인스턴스 메소드 구현
fn[proto].implement=fn.statics=function(o,optFn){
//o가 객체 객체임을 보장합니다. o가 문자열이면 메소드를 추가할 때입니다. , o가 객체라면 일괄적으로 추가된다는 의미입니다
//o에서 복사해야 하므로
o=typeofo=='string'?(function(){
varobj= { };
obj[o]=optFn;
returnobj;
}()):o
//인스턴스 메소드 또는 정적 메소드 추가, 정적 메소드 구현
process(this,o,supr);
returnthis;
}
//백엔드 사용, nodejs
if(typeofmodule!=='undefine' &&module .exports){
module.exports=klass;
}else{
varold=context.klass;
//충돌 방지
klass.noConflect=function(){
context.klass=old;
returnthis;
//프론트엔드 브라우저의 경우
//window.kclass=kclass;
context.klass=klass;
}(이것,'함수')


三、还有一种简单实现
实现思路很简单,就是利用ECMAScript5原型式继承Object.create方法,封装成一个方法,如果不支持ECMAScript5的环境,就平移退化到
复制代码 代码如下:

functionF(){};
F.prototype=superCtor.prototype;
ctor.prototype=newF();
ctor.prototype.constructor=ctor;

同样的,除最后一个参数是当前类的方法声明,其它参数均做为继承父类,需要循环继承,但当这里处理的相对比较简单,没涉及到覆盖。你可以自己动手添加。
复制代码 代码如下:

varClass=(function(){
/**
*Inheritsfunction.(node.js)
*
*@paramctor子类的构造函数。
*@paramsuperctorsuperclass 的构造函数。
*/
varinherits=function(ctor,superCtor){
//显式的指定父类
ctor.super_=superCtor;
//ECMAScript5原型式继承并解除引用
if(Object.create){
ctor.prototype=Object.create(superCtor.prototype,{
constructor:{
value:ctor,
enumerable:false,
writable:true,
configurable:true
}
});
}else{
//无Object.create方法的平稳退化
functionF(){};
F.prototype=superCtor.prototype;
ctor.prototype=newF();
ctor.prototype.constructor=ctor;
}
};
/**
*类函数。
*/
returnfunction(){
//最后一个参数是新类方法、属性和构造函数声明
varsubClazz=arguments[arguments.length-1]||function(){};
//initialize是构造函数,否构造函数就是一个空函数
varfn=subClazz.initialize==null?function(){}:subClazz.initialize;
//继承除最一个参数以的类,多继承,也可以用作扩展方法
for(varindex=0;indexinherits(fn,arguments[index]);
}
//实现新类的方法
for(varpropinsubClazz){
if(prop=="initialize"){
continue;
}
fn.prototype[prop]=subClazz[prop];
}
returnfn;
}
})();

看下面实例:
复制代码 代码如下:

/**
*Cat类的定义。
*/
varCat=Class({
/**
*构造函数。
*
*@paramname猫的名字
*/
initialize:function(name){
this.name=name;
},
/**
*吃功能。
*/
eat:function(){
alert(this.name "iseatingfish.");
}
});
/**
*BlackCat类的定义。
*/
varBlackCat=Class(Cat,{
/**
*构造函数。
*
*@paramnameCat 的名字。
*@paramageCat'sage。
*/
initialize:function(name,age){
//calltheconstructorofsuperclass.
BlackCat.super_.call(this,name);
this.age=age;
},
/**
*吃功能。
*/
eat:function(){
alert(this.name "(" this.age ")iseatingdog.");
}
});
/**
*BlackFatCat类的定义。
*/
varBlackFatCat=Class(BlackCat,{
/**
*构造函数。
*
*@paramnameCat 的名字。
*@paramageCat'sage。
*@paramweight猫的体重。
*@paramweightCat'sweight.
*/
initialize:function(name,age,weight){
//calltheconstructorofsuperclass.
BlackFatCat.super_.call(this,name,age);
this.weight=weight;
},
/**
*吃功能。
*/
eat:function(){
alert(this.name "(" this.age ")iseatingdog.Myweight:" this.weight);
}
});
/**
*DogClass 的定义。
*/
varDog=Class({});
varcat=newBlackFatCat("John",24,"100kg");
cat.eat();
//true
alert(catinstanceofCat);
//true
alert(catinstanceofBlackCat);
//true
alert(catinstanceofBlackFatCat);
//true
alert(cat.constructor===BlackFatCat);
//false
alert(catinstanceofDog);

四、mootools类库的Class

源码解析可以看这里:http://www.cnblogs.com/hmking/archive/2011/09/30/2196504.html
看具体用法:
a、新建一个类 代码如下:


varCat=newClass({
initialize:function(name){
this.name=name;
}
});
varmyCat=newCat('Micia');
alert(myCat.name);//alerts'Micia'
varCow=newClass({
initialize:function(){
alert('moooo');
}
});

b. 상속 구현
코드 복사 코드는 다음과 같습니다.

varAnimal =newClass( {
initialize:function(age){
this.age=age;
}
})
varCat=newClass({
확장:동물,
initialize: function(name,age){
this.parent(age);//callsinitalizemethodofAnimalclass
this.name=name;
}
})
varmyCat=newCat(' Micia', 20);
alert(myCat.name);//alerts'Micia'.
alert(myCat.age);//alerts20

c. 확장 클래스
코드 복사 코드는 다음과 같습니다.

varAnimal=newClass({
initialize:function(age ){
this.age=age;
}
})
varCat=newClass({
Implements:Animal,
setName:function(name) ){
this .name=name
}
})
varmyAnimal=newCat(20)
myAnimal.setName('Micia')
alert(myAnimal.name) );//alerts' Micia'
5. JavaScript 이해: Nectar
사용 예를 먼저 살펴보세요a.


코드 복사 코드는 다음과 같습니다. //Create class Person
varPerson=Class( object,{
Create:function( name,age){
this.name=name;
this.age=age
},
SayHello:function(){
Alert("안녕하세요, 저는" .name "," this.age "yearsold.")
}
})
varBillGates=New(Person,["BillGates",53] );
BillGates.SayHello() ;


b.상속 클래스


코드 복사 코드는 다음과 같습니다. //Employee가 Person을 상속함
varEmployee=Class(Person,{
Create:function(name,age,salary){
Person.Create .call(this,name,age);
//기본 클래스의 생성자 호출
this.salary=salary
},
ShowMeTheMoney:function(){
alert( this.name "$" this.salary);
}
})
varSteveJobs=New(Employee,["SteveJobs",53,1234])
SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();


다음은 소스 코드 분석입니다. 분명히 추가 New 메서드가 있으며 클래스 생성과 새 클래스의 인스턴스가 교묘하게 캡슐화됩니다. 의미있는 전체를 형성! 또 다른 차이점은 모든 클래스가 함수가 아닌 리터럴을 기반으로 한다는 것입니다. 코드는 매우 짧지만 원리는 풍부하고 기발하기 때문에 꼼꼼히 음미해볼 수 있습니다!


코드 복사 코드는 다음과 같습니다. //클래스를 생성하는 함수, 사용 클래스 및 상속 관계 선언
functionClass(aBaseClass,aClassDefine){
//클래스의 임시 함수 셸 만들기
functionclass_(){
this.Type=aBaseClass
/ /각 클래스에 상속된 클래스를 참조하는 규칙 A Type 속성을 제공합니다.
for(varmemberinaClassDefine)
this[member]=aClassDefine[member]
//클래스의 모든 정의를 현재 생성된 클래스에 복사합니다. class
}; class_.prototype=aBaseClass;
returnnewclass_()
};
//모든 클래스의 객체 생성에 사용되는 함수
functionNew(aClass ,aParams){
//객체에 대한 임시 함수 셸을 생성합니다
functionnew_(){
this.Type=aClass;
//또한 다음을 기반으로 각 객체에 Type 속성을 할당합니다. 객체가 속한 클래스에 액세스할 수 있습니다.
if(aClass.Create)
aClass.Create.apply(this, aParams)
//모든 클래스의 생성자가 Create라고 하는 데 동의합니다. , DELPHI와 유사합니다
};
returnnewnew_()
};


분석되지 않은 곳이 많아 부정확한 부분이 있을 수 있으니 정정해 주시기 바랍니다.
위 분석을 읽은 후 정보에 따라 자신만의 캡슐화 클래스 라이브러리를 작성할 수도 있습니다. 구현 방법은 개인 취향에 따라 다릅니다. 하지만 기본 아이디어는 프로토타입 기반 상속 방식과 동일하며 새로운 순환 복사 방식이다.

원문 출처: Mu Yi http://www.cnblogs.com/pigtail/
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.