[Typescript] Implicit extension

Falcon·2022년 6월 8일
1

javascript

목록 보기
17/28
post-thumbnail

상속받은 클래스는 항상 생성자에서 super()를 호출해야한다.

그렇지 않으면 다음과 같은 에러가 발생한다.

Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

[Description]
When used in a constructor, the super keyword appears alone and must be used before the this keyword is used. The super keyword can also be used to call functions on a parent object.

- Mozilla docs

예제

다음과 같이 커스텀 에러 클래스를 생성했다고 해보자.

export class CustomError extends Error {
    readonly #status : string = 'fail';

    constructor(message: string) {
        super(message);
        this.name = this.constructor.name;
    }

    get status(): string {
        return this.#status;
    }

    getJsonMessage() : string {
        return JSON.stringify({
            status: this.status,
            name: this.name,
            message: this.message,
        });
    }
}
// 이런식으로 커스텀 에러클래스를 super() 없이 상속받으면 뚝배기 깨진다.
export class InvalidParameter extends CustomError{
    constructor(param: string) {
        this.param = this.param;
    }
}

⚠️ Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
또는
Constructors for derived classes must contain a 'super' call.

예외 상황 (Implicit constructor)

export class InvalidParameter extends CustomError{
// 👉🏻 생성자 아예 생략
}

암시적인 생성자로 생성자를 위와 같이 아예 생략해버리는 경우 내부적으로 다음과 같이 처리된다.

export class InvalidParameter extends CustomError{
    constructor(...args) {
		super(...args);
    }
}

왜 super 를 강제 호출하게 했을까?

모든 자식 객체는 부모 객체와 함께 생성된다.
자식 클래스는 부모 클래스의 멤버 필드의 복사본을 가지지 않는다.
부모 클래스를 가리키는 'Reference' 를 갖고있다.
이는 중복을 줄이는 프로그래밍 패러다임의 기본 정신이 담긴 구조라 할 수 있겠다.
(모든 멤버변수 복사본을 가질 경우 메모리를 얼마나 낭비할지 생각해보라!)

따라서 자식 생성시 부모 객체를 함께 생성하고 자식 객체에서 this 로 접근했을 때 없는 멤버 변수는 부모에서 찾는 메커니즘을 갖고있다.

자바스크립트, 타입스크립트에선 굳이 super가 아닌 this 로 멤버변수에 접근하더라도
자식 -> 상위 부모 -> 그 다음 상위부모 -->>> 최고 부모
순서를 거친다.


📝 결론

  • 서브 클래스 생성자에서 반드시 super() 를 호출할 것
  • 혹은 생성자를 아예 생략해 부모와 같은 생성자를 사용한다.

🔗 Reference

profile
I'm still hungry

0개의 댓글