자바스크립트 완벽 가이드/ 클래스, 생성자, 프로토타입

생성자

new 연산자는 아무 프로퍼티도 없는 새 객체를 생성한 후 new 연산자 뒤에 있는 함수를 호출하고, this 키워드가 새로 생성된 객체를 가리키게 한다. 이런 식으로, new 연산자와 함께 사용되도록 설계된 함수를 생성자 함수라고 하거나 간단하게 생성자라고 부른다. 생성자는 새로운 객체를 초기화하고, 객체에 있는 프로퍼티 중에서 사용되기 전에 미리 값이 할당되어야 하는 프로퍼티들의 초기값을 할당한다.

자바스크립트에서는 간단하게 this가 가리키는 객체에 몇 가지 프로퍼티들을 추가하는 여러분만의 생성자 함수를 정의할 수 있다.

function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    // 주의! 여기에는 return 문이 없다.
}


var rect1 = new Rectangle(2, 4);
var rect2 = new Rectangle(8.5, 11);

Rectangle( ) 생성자를 사용하여 만드는 모든 객체에는 width와 height라는 프로퍼티가 있다.

프로토타입과 상속

자바스크립트의 모든 객체는 프로토타입이라고 불리는 또 다른 객체를 내부적으로 참조할 수 있다. 그리고 객체는 프로토타입의 프로퍼티들을 자신의 프로퍼티로 가져온다. 다시 말해, 자바스크립트의 객체는 자신의 프로토타입에 있는 프로퍼티들을 상속 받는다.

빈 객체가 생성되면, new 연산자는 해당 객체의 프로토타입을 설정한다. 이때 생성된 객체는, 자신을 만들어낸 생성자의 prototype 프로퍼티를 자신의 프로토타입으로 설정한다. 모든 함수에는 prototype 이라는 프로퍼티가 있는데, 이것은 함수가 정의될 때부터 자동적으로 생성되고 초기화된다.

prototype 프로퍼티의 초기값은 프로퍼티가 하나 있는 객체로 지정된다. 이 프로퍼티는 constructor라고 불리는데 프로토타입이 연관되어 있는 생성자 함수를 가리킨다. 여러분들이 프로토타입 객체에 추가한 프로퍼티들은 생성자를 사용하여 초기화되는 모든 객체의 프로퍼티로 나타난다.

// 생성자 함수는 각 인스턴스의 프로퍼티가 다른 값이 되도록 초기화시킨다.
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}


// 프로토타입 객체는 각 인스턴스들이 공유해야 하는 프로퍼티나 메서드를 정의한다.
Rectangle.prototype.area = function( ) { return this.width * this.height; }

생성자는 객체들의 클래스를 위한 이름을 정의하고, width나 height와 같이 인스턴스마다 다를 수 있는 프로퍼티의 값을 초기화시킨다. 그리고 프로토타입 객체는 생성자와 연결되며, 이 생성자를 통해 생성되는 객체들은 프로토타입이 가진 프로퍼티들을 똑같이 상속받는다. 이 말은 프로토타입 객체가 메서드나 상수 같은 프로퍼티들을 위치시키기에 좋은 곳임을 의미한다.

생성자 내부에 메서드를 추가하는 방법이 있긴 하지만, 한 클래스에 속하는 객체들이 공유하게끔 만들어진 메서드에 일반적인 프로퍼티를 사용하는 것이 비효율적이기 때문에, 프로토타입을 사용하는 것이 낫다. –사실 나는 그게 왜 비효율적인지 모르겠으나, 경험 많은 프로그래머가 책에 그렇게 썼으니 그렇게 이해하고 메서드를 객체 내부가 아닌 프로토타입으로 빼도록 하자.

상속이 프로퍼티 값을 찾는 과정의 일부로서 자동적으로 발생한다는 사실을 유념하여 보라. 프로퍼티는 프로포타입에서 새로운 객체로 복사되는 것이 아니다. 마치 새로운 객체의 프로퍼티인 것처럼 보일 뿐이다. 이는 두 가지 중요한 사실을 의미한다. 우선, 프로토타입 객체를 사용하면 각 객체가 프로토타입의 프로퍼티를 상속받기 때문에 이들이 필요로 하는 메모리 양을 상당히 줄일 수 있다. 다음으로, 프로토타입에 새로운 프로퍼티가 추가되면, 이미 생성되었던 객체일지라도 추가된 프로퍼티를 그대로 상속 받는다. 이것은 (비록 좋은 생각은 아닐 수도 있지만) 기존의 클래스에 새로운 메서드를 추가할 수 있다는 사실을 말한다.

상속받은 프로퍼티는 객체의 일반적인 프로퍼티처럼 작동한다. 그리고 이 프로퍼티들은 for/ in 루프를 통해 열거될 수 있으며, in 연산자를 사용하여 시험할 수 있다. 또한 Object.hasOwnProperty( ) 메서드를 사용해 이들을 종류별로 구별해 낼 수도 있다.

상속받은 프로퍼티의 읽기와 쓰기

클래스에는 프로퍼티의 집합과 더불어 한 개의 프로토타입 객체가 있다. 클래스의 인스턴스는 여러 개가 있을 수 있는데, 이들은 각각 프로토타입의 프로퍼티들을 상속 받는다. 한 개의 프로토타입 프로퍼티는 여러 개의 객체들이 상속받을 수 있기 때문에, 자바스크립트에서는 프로퍼티 값을 읽거나 쓸 때 비대칭성을 의무적으로 지키게 하고 있다.

만일 객체 o의 프로퍼티인 p를 읽을 때, 자바스크립트는 o에 p라는 이름을 가진 프로퍼티가 있는지 검사한다. 만약 없다면 o의 프로토타입 객체에 p라는 프로퍼티가 있는지 검사한다. 이것이 바로 프로토타입 기반의 상속이 작동할 수 있는 이유다.

반면, 자바스크립트는 여러분이 프로퍼티의 값을 쓰려고 할 때는 프로토타입 객체를 사용하지 않는다. 만일 객체 o에 p라는 프로퍼티가 없을 떄, 프로퍼티 o.p의 값을 설정하려고 하는 상황을 생각해 보자. 더 나아가 자바스크립트가 이런 상황을 더욱 진행시켜 o의 프로토타입 객체에 있는 p를 찾고, 프로토타입의 프로퍼티 값을 설정할 수 있게 한다고 생각해 보라. 그러면 의도와 전혀 다르게 모든 객체의 p 값을 바꿔 버리게 된다.

따라서 프로퍼티의 상속은 프로퍼티를 쓸 때가 아닌 읽을 때만 일어난다. 여러분이 만약 객체 o가 프로토타입에서 상속받은 프로퍼티 p를 설정하려고 하면, 이때부터 o에는 새로운 프로퍼티인 p가 만들어진다. 이제 o에는 p라고 이름 붙은 자신만의 프로퍼티가 생기고, 더이상 p의 값을 프로토타입에서 상속 받지 않는다. 긜고 자바스크립트는 여러분이 p의 값을 읽으려 할 때, 먼저 o의 프로퍼티들을 살펴본다. 이때, 자바스크립트는 o에 정의되어 있는 p를 찾으므로 프로토타입 객체를 검색하지 않으며 그곳에 있는 p의 값을 절대 찾지 않는다. 우리는 종종 이것을 o에 있는 프로퍼티 p가 프로토타입 객체에 있는 프로퍼티 p를 ‘가렸다(shadows)’ 혹은 ‘숨겼다(hides)’ 라고 말한다.

프로토타입의 프로퍼티들은 클래스의 모든 객체가 공유하기 때문에, 모든 객체가 같이 사용하는 프로퍼티들을 정의해 놓는 것이 이해하기 쉽다. 이 점은 프로토타입이 메서드를 정의해 두기에 안성맞춤이라는 것을 말한다. 그 외에 상수 값인 프로퍼티들도 프로토타입의 프로퍼티로 정의되는 것이 적당하다. 만약, 여러분의 클래스가 굉장히 자주 사용되는 기본값을 프로퍼티로 정의한다면 이런 프로퍼티와 그 기본값을 프로토타입 객체에 정의해 둘 수도 있다. 이렇게 하면, 기본값을 사용하지 않는 일부 객체들만 그들이 원하는 값이 되도록 재정의하게 할 수 있다. –요는 이것이구만, 모든 객체가 쓰는 것은 당연히 클래스에 있어야 하는데, 많은 객체가 쓰는 데 어떤 일부 객체는 안 쓰는 것은 프로토타입에 둔다. 혹은 어떤 다른 객체는 다르게 쓴다면 그건 재정의 해서 쓸 수 있게 –shadows나 hides나– 한다. 하나 궁금한 것은 메서드는 왜 프로토타입에 넣는 걸까?

내장형 타입의 확장

사용자 정의 클래스만 프로토타입 객체가 존재하지는 않는다. String이나 Date 같은 내장형(built-in) 클래스에도 프로토타입이 있으며, 여러분들은 여기에 값을 할당할 수 있다.

내장형 타입을 여러분이 만든 메서드를 사용하여 확장시키는데는 많은 논란이 있다.

Object.prototype에는 어떤 프로토타입도 추가해서는 안 된다. Object.prototype에 추가된 것은 빈 객체의 열거 가능한 프로퍼티가 되며, 객체를 연관배열로 사용하는 코드가 작동하지 않게 된다.

자바스크립트의 클래스 시뮬레이션

자바스크립트가 객체라는 데이터 타입을 지원하기는 하지만, 클래스를 구체적으로 표현할 수 있는 방법은 제공하지 않는다. 하지만 자바나 C++ 같은 클래스 기반의 언어가 지원하는 기능들을 흉내낼 수는 있다.

인스턴스 프로퍼티

모든 객체에는 자신만의 인스턴스 프로퍼티 사본이 있다. 다시 말해, 한 클래스에 속하는 객체가 열 개 있다면 인스턴스 프로퍼티 사본이 열 개 만들어진다. 자바스크립트에서 객체의 프로퍼티는 기본적으로 인스턴스 프로퍼티가 된다.

인스턴스 메서드

인스턴스 메서드는 데이터 값이 아니라 메서드라는 점을 제외하면 인스턴스 프로퍼티와 상당히 비슷하다. 인스턴스 메서드는 특정한 객체나 인스턴스가 호출한다. 인스턴스 메서드는 메서드를 호출한 객체나 인스턴스를 참조하기 위해서 this 키워드를 사용한다. 클래스의 인스턴스가 인스턴스 메서드를 호출할 수는 있지만, 인스턴스 프로퍼티 같이 각 객체마다 그들만의 메서드 사본을 가지는 것은 아니다. 대신 각 인스턴스 메서드는 클래스의 모든 인스턴스가 공유한다. 자바스크립트에서 클래스의 인스턴스 메서드는 생성자의 프로토타입 객체가 가진 프로퍼티에 함수 값을 넣어주는 방법을 통해 정의된다. 이 생성자를 통해 생성되는 모든 객체는 함수에 대한 참조를 상속받고 이를 공유한다.

클래스 프로퍼티

클래스 프로퍼티란 클래스의 각 인스턴스가 아닌 클래스 자체와 연관되어 있는 프로퍼티를 말한다. 클래스 프로퍼티는 클래스의 인스턴스가 몇 개나 생성되는지에 상관없이 한 개만 존재한다. 인스턴스 프로퍼티가 인스턴스를 통해 접근되듯이 클래스 프로퍼티는 클래스 자신을 통해 접근된다. 클래스 프로퍼티는 한 개의 사본만 있기 때문에 필수적으로 전역에서 접근할 수 있어야 한다. 반면 이들의 유용한 점은 클래스와 연관되어 있고, 논리적인 보호 영역(niche)이 있다는 점이다. 논리적인 보호 영역은 자바스크립트의 네임스페이스에 있는 지점인데 같은 이름을 가진 다른 프로퍼티에 의해 덮어씌워지지 않는다.

자바스크립트에서도 생성자 함수의 프로퍼티를 정의하여 클래스 프로퍼티를 흉내낼 수 있다. 예컨대 1×1 사각형을 저장하기 위해 Rectangle.UNIT 라는 클래스 프로퍼티를 만들고 싶다면 아래와 같이 하면 된다.

Rectangle.UNIT = new Rectangle(1, 1);

Rectangle은 생성자 함수지만 자바스크립트 함수는 객체이기 때문에 다른 객체에 프로퍼티를 만드는 것과 똑같이 함수 프로퍼티를 만들 수 있다.

클래스 메서드

클래스의 메서드는 클래스의 인스턴스보다 클래스 자체와 연관이 있다. 클래스 메서드는 특정 인스턴스를 통해 호출되지 않고 클래스 자체를 통해 호출된다. Date.parse( ) 메서드는 클래스 메서드의 한 예이다.

클래스 메서드는 생성자 함수를 통해 호출되기 때문에 this 키워드는 특정한 인스턴스를 참조하지 않는다. 대신 생성자 함수 자체를 참조한다. (일반적으로 클래스 메서드는 this를 전혀 사용하지 않는다.)

클래스 프로퍼티와 마찬가지로 클래스 메서드도 전역에서 접근할 수 있다. 클래스 메서드는 특정한 객체에서 작동하는 것이 아니기 때문에, 쉽게 클래스를 통해 호출되는 함수라고 생각할 수 있다.

private 멤버

객체지향 언어에서 널리 사용되는 ‘데이터 캡슐화’ 라는 기술은 프로퍼티를 private 화 하고 특별한 메서드를 통해서만 이들을 읽거나 쓸 수 있게 한다. 자바스크립트는 클로저를 사용하여 이를 흉내낼 수 있지만 이를 위해서는 인스턴스마다 접근 메서드가 저장되어 있어야 한다. 이들은 프로토타입 객체에서 상속 받지 못한다.

아래의 코드에서 width와 height에 접근하기 위해서는 getWidth, getHeight 를 이용해야만 할 수 있다.

function ImmutableRectangle(w, h) {
    // 이 생성자는 초기화시킬 객체의 width와 height 프로퍼티를 저장하지 않는다.
    // 대신에 객체의 접근 메서드들을 정의해준다. 
    // 이 메서드들은 클로저이며, width와 height의 값은 메서드의 유효 범위 체인 안에 있다.

    this.getWidth = function ( ) { return w; }
    this.getHeight = function ( ) { return h; }
    }


    // 클래스의 프로토타입 객체에 일반 메서드가 올 수 있음을 주목하라 
    ImmutableRectangle.prototype.area = function ( ) {
    return this.getWidth( ) * this.getHeight( );
}

공통적인 객체 메서드

toString( ) 메서드

toString( )에 깔려있는 기본 아이디어는 객체의 각 클래스가 자신을 문자열로 표현할 수 있게 만드는 것인데, 이를 위해서 객체를 문자열 형태로 변환할 수 있게 적절한 toString( ) 메서드가 정의되어야 한다. 여러분이 하나의 클래스를 정의하면 클래스의 인스턴스가 문자열로 변환될 수 있게 반드시 toString( ) 메서드를 정의해야 한다. 이 문자열에는 변환되는 객체에 대한 정보가 들어있어야 하는데, 이렇게 해두면 나중에 디버깅할 때 유용하게 사용할 수 있다. 뿐만 아니라 문자열이 적당하게 구성되면 그 자체만으로도 프로그램 내에서 유용한 정보가 될 수 있다.

valueOf( ) 메서드

valueOf( ) 메서드는 toString( ) 과 상당히 유사하지만, 자바스크립트가 객체를 Number 같은 문자열 외의 기본 타입으로 변환하려 할 때 호출하게 된다. 할 수 있는 한 이 함수는 this 키워드가 참조하고 있는 객체의 값을 나타낼 수 있는 기본 타입의 값을 반환해야 한다.

비교 메서드

자바스크립트의 동등 연산자는 값이 아닌 참조를 통해 객체를 비교한다. 만약 여러분이 클래스를 정의하고 이 클래스의 인스턴스들을 비교하고 싶다면, 이를 위해 적절한 메서드들을 정의해야만 한다.

슈퍼 클래스와 서브 클래스

다른 클래스 기반의 객체지향 언어들은 클래스의 계층에 대해 명확한 개념을 가지고 있다. 모든 클래스는 자신의 프로퍼티와 메서드를 상속받는 슈퍼 클래스를 가질 수 있다. 어떤 클래스라도 확장되거나 서브 클래스화되어, 결과로 만들어지는 서브 클래스가 자신의 행동을 그대로 상속받을 수 있다. 자바스크립트는 클래스 기반의 상속 대신 프로토타입 상속을 지원한다. 하지만 자바스크립트를 사용하여도, 생각할 수 있는 클래스 계층을 유사하게 만들 수 있다.

자바스크립트에서는 Object 클래스가 가장 일반화되어 있는 클래스이며, 다른 클래스들은 이 클래스의 서브 클래스이거나 이를 좀 더 구체화시킨 클래스이다. 다르게 말하면 Object 클래스는 모든 내장 클래스의 슈퍼 클래스이며, 모든 클래스는 Object 클래스에서 몇 개의 기본적인 메서드를 상속 받는다.

프로토타입객체는 Object( ) 생성자를 사용하여 만들어진다. 이 말은 프로토타입 객체도 Object.prototype의 프로퍼티들을 상속받는다는 것을 의미한다. 프로토타입 기반의 상속은 한 개의 프로토타입에 제한되지 않는다. 대신 프로토타입 객체의 체인을 사용한다.

즉 Complex 객체는 Complex.prototype과 Object.prototype의 프로퍼티들을 상속 받는다. 여러분이 Complex 객체의 프로퍼티를 찾으려고 하면 우선 객체 자체에 있는 프로퍼티들을 검색한다. 만약 원하는 프로퍼티가 없다면 Complex.prototype 객체를 검색한다. 원하는 프로퍼티가 이 객체에도 없다면 마지막으로 Object.prototype 객체를 검색해 본다.

자바스크립트 클래스의 서브클래스화

// 여기 있는 것은 간단한 Rectangle 클래스이다.
// 이 클래스에는 너비와 높이를 위한 프로퍼티, 그리고 넓이를 계산할 수 있는 메서드가 정의되어 있다.
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}
Rectangle.prototype.area = function ( ) { return this.width * this.height; }


// 이것은 Rectangle 클래스를 어떻게 슈퍼 클래스화 하는지 보여준다.
function PositionedRectangle(x, y, w, h) {
    // 우선 width와 height 값을 초기화할 수 있게 새로운 객체의 슈퍼 클래스 생성자를 호출한다.
    // 초기화될 객체의 메서드로 생성자를 호출할 수 있게 call( ) 메서드를 사용한다.
    // 이 기법은 생성자 체이닝(chaining)이라고 불린다.
    Rectangle.call(this, w, h);


    // 이제 사각형의 왼쪽 위의 좌표를 저장한다.
    this.x = x;
    this.y = y;
}


// 만약 PositionedRectangle( ) 생성자를 정의할 때 생성되는 기본 프로토타입 객체를 사용하면 Object 클래스의 슈퍼 클래스를 얻는다.
// Rectangle를 슈퍼 클래스화 시키려면 명시적으로 프로토타입 객체를 생성해야 한다.
PositionedRectangle.prototype = new Rectangle( );


// 이 프로토타입 객체는 상속을 목적으로 만든 것이지만 Rectangle 클래스의 객체에 있는 width와 height 프로퍼티를 원하지는 않기 때문에 프로토타입에서 삭제한다.
delete PositionedRectangle.prototype.width;
delete PositionedRectangle.prototype.height;


// 프로토타입 객체가 Rectangle( ) 생성자를 사용하여 만들어졌기 때문에 constructor 프로퍼티는 이 생성자를 참조한다.
// 하지만, 우리는 PositionedRectangle 객체가 다른 constructor 프로퍼티를 가지길 원하기 때문에 constructor 프로퍼티의 기본값을 다시 할당한다.
PositionedRectangle.prototype.constructor = PositionedRectangle;


// 이제 우리가 만든 서브 클래스의 프로토타입 객체가 만들어졌으며, 여기에 인스턴스 메섣를 추가해 넣을 수 있다.
PositionedRectangle.prototype.contains = function(x, y) {
    return ( x > this.x && x < this.x + this.width &&
    y > this.y && y < this.y + this.height );
}

자바스크립트에서 서브 클래스를 만드는 것이 Object 클래스에서 직접 상속을 받는 것처럼 간단하지는 않다. 먼저 서브 클래스의 생성자에서 슈퍼 클래스의 생성자를 호출해야 한다. 이때, 슈퍼 클래스의 생성자가 새로 만든 객체의 메서드인 것처럼 호출되는데 주의하라. 그 다음, 서브 클래스 생성자의 프로토타입 객체를 설정하기 위한 몇 가지 기술이 필요하다. 이 작업을 할 때는 반드시 프로토타입 객체를 명시적으로 슈퍼 클래스의 인스턴스로 만들어야 하고, 그 후에 프로토타입 객체의 constructor 프로퍼티를 명시적으로 설정해 주어야 한다. 경우에 따라서, 프로토타입 객체가 자신의 프로토타입에서 상속받은 프로퍼티들이 중요할 수 있다. 이때 여러분은 프로토타입 객체에서 슈퍼 클래스의 생성자가 만든 프로퍼티들을 삭제할 수 있다.

생성자 체이닝

위의 예에서 PositionedRectangle( ) 생성자 함수는 상위 클래스의 생성자 함수를 명시적으로 호출해야 했는데, 이런 작업을 생성자 체이닝이라 부르며 하위 클래스를 생성할 때 굉장히 자주 사용된다. 여러분은 다음과 같이 하위 클래스의 프로토타입 객체에 superclass 라는 프로퍼티를 추가하는 방법을 통해 생성자 체이닝을 위한 문법을 간소화 시킬 수 있다.

// 상위 클래스 생성자에 대한 참조를 저장한다.
PositionedRectangle.prototype.superclass = Rectangle;

여기서 정의된 프로퍼티를 사용하여 생성자 체이닝을 더욱 간단히 만들 수 있다.

function PositionedRectangle(x, y, w, h) {
    this.superclass(w, h);
    this.x = x;
    this.y = y;
}

상위 클래스 생성자 함수가 this 객체를 통해 호출되는데 주목하라. 이것은 여러분이 이 객체의 메서드로서 상위 클래스 생성자를 호출하기 위해 더이상 call( )이나 apply( )를 사용할 필요가 없음을 의미한다.

재정의된 메서드 호출하기

하위 클래스가 상위 클래스에 있는 메서드와 똑같은 이름의 메서드를 정의하면, 하위 클래스는 이 메서드를 재정의 한다. 예를 들어, 여러분이 어떤 클래스에 toString( ) 메서드를 정의하면 이 메서드는 Object의 toString( ) 메서드를 재정의 한다.

다른 메서드를 재정의하는 메서드는 종종 기존 메서드에 있던 기능을 완전히 교체하기보다 확장시킨다. 이를 위해서는 메서드가 자신이 재정의하는 메서드를 불러올 수 있어야 한다. 이것은 어떤 관점에서 보면, 이 장 앞에서 생성자에 대해 설명했던 것처럼 메서드 체이닝의 일종이다. 하지만 재정의된 메서드를 호출하는 것은 상위 클래스의 생성자를 호출하는 것보다 불편하다.

상속 없이 확장하기

하위 클래스화와 상속이 클래스를 확장하는 유일한 방법이 아니라는 점에서 자바스크립트는 꽤 유연한 언어다. 자바스크립트 함수들은 데이터 값이므로 함수를 한 클래스에서 다른 클래스로 복사할(혹은 빌려갈) 수 있다.

다른 클래스에서 사용하기 위해 클래스의 메서드를 빌려오기

// 한 클래스의 메서드를 다른 클래스에서 사용하기 위해 빌려온다.
// 전달인자는 클래스들의 생성자 함수가 되어야 한다.
// Object와 Array, Date, RegExp 같은 내장 타입의 메서드는 열거 가능하지 않으며 아래 메서드를 통해 빌려 올 수 없다.
function borrowMethods(borrowFrom, addTo) {
    var from = borrowFrom.prototype; // 메서드를 빌려올 프로토타입 객체
    var to = addTo.prototype; // 확장할 프로토타입 객체


    for(m in from) { // 프로토타입의 모든 프로퍼티에 대해 반복한다.
        if ( typeof from[m] != "function" ) continue; // 함수가 아닌 것은 무시한다.
        to[m] = from[m]; // 메서드를 빌려온다.
    }
}

많은 메서드는 자신을 정의한 클래스에 튼튼하게 연결되어 있으므로 메서드를 다른 클래스에서 사용하려는 것은 말이 되지 않는 것 같지만, 일반적으로 메서드를 클래스나 특정한 프로퍼티를 정의하는 클래스에서 사용하기 적합하게 작성할 수 있다.

객체 타입 판단하기

자바스크립트는 타입의 제약이 느슨하며, 자바스크립트 객체는 더욱 타입 제약이 느슨하다. 여러분은 자바스크립트에 있는 여러가지 기법을 사용하여 임의의 값이 어떤 타입에 속하는 것인지 판단할 수 있다.

instanceof와 constructor여러분이 어떤 값이 기본 타입이나 함수가 아니라 객체라고 판단하면 이에 관련하여 더 많은 정보를 얻기 위해 instanceof 연산자를 사용할 수 있다. 예를들어 x가 배열이라면 다음 코드는 true로 평가된다.

x instanceof Array

만약 여러분이 객체가 특정한클래스의 인스턴스이고 그 클래스의 하위 클래스는 인스턴스는 아니라는 사실을 테스트하고 싶다면 그 객체의 constructor 프로퍼티를 검사할 수 있다.

var d = new Date( ); 
var isobject = d instanceof Object; // true로 평가된다.
var realobject = d.consturctor == Object; // false로 평가된다.
[ssba]

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.