1. js 클래스 정의 JS는 객체지향 언어가 아니고 클래스에 대한 지원을 제공하지 않기 때문에 기존 언어처럼 클래스를 정의하기 위해 클래스를 사용할 수는 없지만 클로저를 사용할 수 있습니다. js 클래스를 구현하기 위한 js의 캡슐화 메커니즘
function ShapeBase() {
this.show = function()
{
alert("ShapeBase show")
}
init = function(){
alert("ShapeBase init");
};
}
이 클래스는 show 및 init라는 두 가지 메서드를 정의합니다. 흥미로운 점은 다음과 같습니다. 여기서는 var 대신 var를 사용하여 선언합니다.
또한 프로토타입 속성을 사용하여 Shape 메서드를 정의할 수도 있습니다. 🎜>코드 복사
ShapeBase.prototype.init=function()
{
alert("ShapeBase init")
}
위의 글 메서드가 직관적이지 않은 것 같으니 모든 메서드를 함께 작성하면 됩니다.
코드 복사
},
init:function() {
경고 ("ShapeBase init");
}
};
이제 클래스가 작성되었습니다. 테스트를 위해 js를 작성하고 결과가 동일한지 확인해 보겠습니다. 상상한 것과 똑같나요?
코드 복사
}
보세요. 메소드는 C#과 똑같고 결과는 예상한 대로입니다.
지금까지 js 클래스를 생성하는 방법을 배웠지만 인스턴스 메소드만 구현하면 어떻게 될까요? 기음#?
실제로 js에서 정적 메소드를 구현하는 것은 매우 간단합니다. 아래에서 구현 방법을 확인하세요.
코드 복사
}
2. JS 클래스 추상화 및 상속 구현
마찬가지로 클래스 상속 메커니즘은 js에서 지원되지 않지만 상위 클래스의 멤버 메서드를 복사하여 이를 달성할 수 있습니다.
클래스 상속과 마찬가지로 JavaScript에는 추상 클래스를 지원하는 메커니즘이 없습니다. 그러나 JavaScript 언어 자체의 특성을 활용하여 고유한 추상 클래스를 구현할 수 있습니다. , js의 가상 메소드를 살펴보겠습니다. 언어의 전통적인 가상 메소드는 먼저 정의되어야 하며, 가상 메소드를 포함하는 클래스는 추상 클래스이므로 인스턴스화할 수 없습니다. 클래스 내에서 정의되지 않은 메서드로 사용되었지만 this 포인터를 통해 사용되었습니다.
기존 객체 지향과 달리 여기서 가상 메서드는 선언할 필요 없이 직접 사용되며 클래스를 인스턴스화할 수도 있습니다. 🎜>먼저 객체의 확장 메소드를 정의합니다. 하나는 정적 메소드이고 다른 하나는 상속된 프로토타입 복사를 구현하는 데 사용되는 메소드입니다.
코드 복사
코드는 다음과 같습니다.
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this , object]);
}
다음으로 상속된 클래스 Rect를 구현하기 위해 먼저 간단한 메서드를 사용하여 구현합니다.
코드 복사
코드는 다음과 같습니다.
}
이 메서드는 재정의에 사용할 수 없습니다. show 메서드가 변경되면 ShapeBase의 show도 동일한 함수를 가리킵니다. 이는 프로토타입 할당이 단순히 포인팅 주소를 변경하기 때문일 수 있습니다.
위에서도 정의된 경우입니다. :
Rect.prototype.show=function() {
alert("Rect show")
}
그러면 실행 결과는 다음과 같습니다.
function test(){
var s=new ShapeBase( );
s.show(); //결과: 직사각형 표시
var r=new Rect()
r.show();
r.add( );
}
그런 다음 object.extend를 사용하여 상속을 구현하고 다음과 같이 ShapeBase를 수정합니다.
ShapeBase.prototype={
show:function()
{
alert( "ShapeBase show");
},
initialize:function () {
this.oninit();
}
}
Rect 클래스를 구현합니다.
Rect.prototype=(new ShapeBase ).extend({
//새 메소드 추가
add:function() {
alert("Rect add");
},
//쇼를 재정의하려면 이 메소드를 사용하세요. method
show:function() {
alert("Rect show");
},
//가상 메서드 구현
oninit:function() {
alert("Rect oninit");
}
} )
이제 클래스가 작성되었으므로 테스트해 보겠습니다.
function test(src){
ShapeBase.StaticDraw()
var s=new ShapeBase(); 🎜>s.show(); //alert( "ShapeBase 표시")
var r=new Rect()
r.show() //alert("Rect 표시")
r .add();
r.initialize( ); //alert("Rect oninit")
}
그리고 인터넷에서 특수 객체를 사용하는 기사를 봤습니다. 클래스를 생성하는 코드는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.
//
//객체 속성 복사 방법, PrototypeJS의 확장 및 Ext의 Ext.apply와 같은 많은 라이브러리에서 이를 구현했습니다.
//
함수 확장(des, src ) {
if (!des)
des = {};
if (src) {
for (var i in src) {
des[i] = src[i]; 🎜>}
}
return des;
}
var CC = {}; //전역 변수
//
//create를 사용하여 클래스 생성
/ /
CC.create = function(superclass, constructor){
var clazz = (function() {
this.initialize.apply(this, 인수);
}); /매개변수가 없으면 클래스를 직접 반환합니다.
if(arguments.length == 0)
return clazz;
//상위 클래스가 없으면 생성자는 순수 객체여야 합니다. 이번에는 속성을 직접 복사하고 . ,
sprPropty = superclass.prototype ;
if(sprPropty){
//부모 클래스 메서드에 액세스하는 데 사용됩니다.
clazz.superclass = sprPropty;
extend(absObj, sprPropty); >//속성 생성자를 호출하여 속성을 생성합니다. 이것이 구현의 핵심입니다.
extend(absObj, constructor(sprPropty))
// 하위 클래스 인스턴스는 obj.superclass를 통해 상위 클래스 속성에 직접 액세스합니다.
// 너무 많은 참조를 원하지 않으면 이 문장을 주석으로 처리할 수도 있습니다. 대부분의 경우 불필요하기 때문입니다.
absObj.superclass =
//
clazz.constructor = constructor;
}
return clazz;
}
//
//동물 클래스 만들기
//
var Animal = CC. create(null, {
//Attributes
footprint: '- - - - - - =',
//클래스 초기화 메서드, 필수, 이 메서드는 new를 사용하여 클래스를 생성할 때 자동으로 호출됩니다. 위의 정의를 참조하세요.
initialize: function(options){
extend(this , options)
alert('동물 초기화 메서드가 호출됩니다.'); function(){
alert('동물 먹는 방법이 호출됩니다.');
},
move : function(){
alert('나는 'this.footprint' 이렇게 움직이고 있습니다. ');
}
});
//
//Duke 클래스 생성
//
var Duke = CC.create(Animal, function(superclass){
//여기서 이 클래스의 각 인스턴스에서 공유되는 일부 클래스 전역 정적 데이터를 정의할 수 있습니다.
//파생 클래스 인스턴스를 포함한 인스턴스 클래스를 계산합니다.
var static_instance_counter = 0; >function classUtilityFuncHere(){ }
//클래스별 속성을 반환합니다.
return {
//초기화 메서드 다시 작성
//@override
initialize: function(options) {
alert('Duke 클래스 초기화 중..');
//상위 클래스 초기화를 호출합니다. 이 방법은 다른 라이브러리보다 간단하며 상위 클래스가 무엇인지는 중요하지 않습니다.
superclass.initialize. call(this, options);//하위 클래스가 좋아하는 작업을 수행합니다.
alert('Duke 초기화 메서드가 호출됩니다.')//클래스 정적 속성을 읽거나 수정합니다.
static_instance_counter ;
},
//Duke의 자체 이동 메서드를 늘리기 위해 이동 메서드를 다시 작성합니다.
move: function(){
this.footprint = this.footprint 'zzzzzzzz'
superclass. move.call(this);
},
//eat 메서드 다시 작성, 상위 클래스 메서드가 호출되지 않습니다. 즉, 상위 클래스 eat가
eat: function()을 덮어쓰게 됩니다. {
alert('Duke is eating..');
},
//현재 초기화된 Duke 클래스 인스턴스 수를 표시하는 새로운 say 메소드를 추가합니다.
say: function(){
alert('static_instance_counter);
}
}
})
var DukeChild(Duke, function(superclass)); >return {
move: function(){
this.footprint = this.footprint ' =';
superclass.move.call(this);
},
say: function( ){
alert(this.msg || '');
}
})
(function test() {
var Animal = new Animal() ;
animal.eat();
var dukeA = new Duke()
dukeA.move(); >dukeA.say();
var dukeB = new Duke();
dukeB.move()
var dukeC = new DukeChild({msg : '저는 공작의 자녀입니다.'});
dukeC .move()
dukeC.say()
})(); >