[JavaScript] 클래스 상속

자바스크립트에서 클래스의 상속 개념을 정리해 보고자 합니다. 먼저 크기값(width, height) 만을 갖는 Rectangle라는 클래스가 있고 이 클래스를 상속받으면서 위치값(x, y)를 갖는 PositionedRectangle 클래스를 만들어 보는 예를 통해 정리하고자 합니다. (이 글은 인사이트의 자바스크립트 완벽가이드 내용을 읽고 이해하여 짧게 요약한 글입니다)

가장 먼저 Rectangle이라는 클래스 정의 코드입니다.
function Rectangle(w, h)
{
    this.width = w;
    this.height = h;
}

Rectangle.prototype.area = function()
{
    return this.width * this.height;
}

Rectangle.prototype.toString = function() 
{
    return "[" + this.width + ", " + this.height + "]";
}

생성자 함수에서 크기값에 대한 인자 w, h를 받습니다. 그리고 area라는 매서드와 toString이라는 매서드를 정의하고 있습니다. 이후에 Rectangle 클래스를 상속받아 toString 함수를 재정의할때 부모 클래스의 toString을 호출하는 방법을 살펴보도록 하겠습니다.

자, 이제 PositionedRectangle이라는 클래스를 Rectangle 클래스를 상속받아 정의하는 코드를 보겠습니다.
function PositionedRectangle(x, y, w, h)
{
    Rectangle.call(this, w, h);
    
    this.x = x;
    this.y = y;
}

3번 코드에서 상속받을 Rectangle 클래스를 지정합니다. 그리고 PositionedRectangle의 부모 클래스가 Rectangle이라는 것을 명확히 하도록 다음 코드를 추가합니다.

PositionedRectangle.prototype = new Rectangle();

위의 코드의 문제점은 PositionedRectangle의 생성자 함수까지도 Rectangle로 지정된다는 점입니다. PositionedRectangle의 생성자 함수를 다시 자기의 것으로 지정되도록 다음 코드를 추가합니다.

PositionedRectangle.prototype.constructor = PositionedRectangle;

또 한가지 문제가 있는데, 그것은 중복된 데이터입니다. PositionedRectangle는 Rectangle로부터 상속을 받았으므로 Rectangle의 width와 height 데이터를 갖습니다. 그런데 이 값이 각각 2개씩 중복(PositionedRectangle에 하나, PositionedRectangle.prototype에 하나)되어 갖고 있습니다. 해서 중복되지 않도록 제거해 주는 코드가 필요합니다.

delete PositionedRectangle.prototype.width;
delete PositionedRectangle.prototype.height;

이제 옵션으로 PositionedRectangle 자신의 함수를 추가하는 코드입니다.

PositionedRectangle.prototype.contains = function(x y)
{
    return (x > this.x && x < this.x + this.width 
        && y > this.y && y < this.y + this.height);
}

끝으로 부모 클래스의 메서드 함수를 재정의할때 부모 클래스의 메서드 함수를 호출하는 방법입니다. toString 함수를 예로 정리하면, PositionedRectangle에 다음처럼 toString 함수를 재정의할 수 있습니다.

PositionedRectangle.prototype.toString = function()
{
    return "(" + this.x + ", " + this.y + ") " 
        + Rectangle.prototype.toString.apply(this);
}

[JavaScript] 함수 인자의 타입 검사

자바스크립트에서 함수를 만들어 사용할때 그 함수의 인자에 대한 타입은 암묵적인 약속입니다. 이 말은 “이 함수의 인자의 타입은 … 이다”라는 개념에 지나지 않다는 의미입니다. 그러한 개념에서 벗어나 보다 엄격하게 그 타입을 지키도록 하는 방어책이 필요할때 아래의 예를 참고하고자 이 글로 정리해 둡니다.

function sum(a /* Array */)
{
    var isArray = (a instanceof Array);
    var isLikeArray = (a && typeof a == "object" && "length" in a);
  
    if(isArray || isLikeArray)
    {
        var total = 0;
    
        for(var i=0; i        {
            var element = a[i];
            if(!element) continue;
            if(typeof element == "number") 
                total += element;
            else 
                throw new Error("원소는 숫자여야 함");
        }

        return total;
    }
  
    throw new Error("인자는 배열이어야 함");
 }

var a = [1,2,3,4,5];
try 
{
    document.write(sum(a));
} 
catch(e)
{
    document.write(e.message);
}

3번 코드가 전달 받은 인자의 타입이 배열인지를 확인하는 것이고 4번은 배열과 비슷한 객체인지, 즉 length 프로퍼티를 제공하는지를 확인하는 코드입니다. 14번 코드는 배열의 원소가 숫자인지를 확인하는 코드입니다.

이 코드는 인사이트의 JavaScript 완벽 가이드라는 책의 코드를 조금 변형한 것입니다. 자바스크립트에 관해 좋은 책이라고 생각합니다.