첫페이지 > Tip&Tech > JavaScript에서 클래스를 사용할 때의 생성자

JavaScript에서 클래스를 사용할 때의 생성자

2008/03/28

JavaScript에서는 function 객체를 클래스 타입이자 생성자로 사용할 수 있다. 다음은 간단한 예제 코드이다.

function typeClass() {
 
}
 
var oInstance = new typeClass;

인스턴스를 생성할 때 사용한 클래스 겸 생성자인 typeClass는 인스턴스 객체의 constructor 속성으로 접근할 수 있다. 이는 Array, Object 등을 비롯한 JavaScript의 코어 객체도 마찬가지다.

function typeClass() {};
 
var oInstance = new typeClass;
 
alert(oInstance.constructor == typeClass);

한편, 함수의 prototype 속성을 이용하면 상속도 가능하다. 이용해서 한꺼번에 메소드, 프로퍼티를 정의할 수도 있다. 유명한 프레임웍인 prototype.js 도 기본 원리는 다음의 코드와 비슷하게 구현이 되어있다.

function typeClass() {};
 
typeClass.prototype = {
	method : function(){}
};
 
var oInstance = new typeClass;

이제 아까와 마찬가지로 constructor 속성에 접근해보도록 하자.

function typeClass() {};
 
typeClass.prototype = {
	method : function(){}
};
 
var oInstance = new typeClass;
 
alert(oInstance.constructor == typeClass);

어째 결과가 이상하지 않은가? typeof 연산자로 체크해봐도 oInstance.constructor 는 “function”이 아닌 “object” 타입으로 출력된다. 확실한 원인은 모르겠으나 prototype이 재정의되면서 이러한 문제가 발생하는 것 같다. 아래 코드에서는 여전히 constructor 가 function 으로 출력되고, typeClass는 oInstance의 클래스 타입이다.

function typeClass() {};
 
typeClass.prototype.method = function(){};
 
var oInstance = new typeClass;
 
alert(oInstance.constructor == typeClass);

이 같은 문제를 다음과 같은 두 가지 방법으로 해결할 수 있다.

  1. typeClass.prototype 을 재정의하지 않고 각각의 프로퍼티나 메소드를 덧붙인다.
  2. typeClass의 prototype.constructor 를 재정의한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    function typeClass() {
    }
    typeClass.prototype = {
    	method : function() {
    	}
    }
    typeClass.prototype.constructor = typeClass;
     
    var oInstance = new typeClass;
    alert(oInstance.constructor == typeClass);

추가 // prototype.js에는 이런 문제가 수정되어있습니다. 제가 보던 때와는 달리 많이 변경된 것 같습니다. ^^;;

Tip&Tech , ,

  1. 2008/03/29 12:13 | #1

    세 번째 소스 박스에서 상속의 설명이 좀 잘못된것 같네요. classical 상속이든, prototypal 상속이든 function과 function의 관계인데, “var oInstance = new typeClass;”는 생성자를 이용하여 instance를 만드는 것에 불과합니다. oInstance.constructor가 (의도한 바가 아닌)function이 아닌 이유도 그 때문입니다.

  2. 2008/03/30 12:10 | #2

    해당 코드가 상속이라는 의미로 쓰려했던 것은 아니었는데 이제보니 그렇게 썼었네요(퇴근 직전에 급히 쓰느라 그랬나봅니다;;). 클래스를 정의하고 상속을 구현하는데에 prototype 전체를 재정의하는 코드가 있다… 정도가 전달하고자 하는 바였거든요. ^^ 말씀하신대로 해당 코드는 상속에 관한 코드가 아닙니다.

    또한 생각난 김에 prototype.js 의 코드를 확인해봤더니 해당 문제가 수정되어있었습니다(몇 버전 부터지 -_-a). 본문을 업데이트합니다. ^^

  1. 아직은 트랙백이 없습니다.
댓글이 닫혀 있습니다.