typescript

프로토타입 체인 문제 해결법(Object.setPrototypeOf)

자바스크립트나 TypeScript를 사용하면서 '에러 처리'는 항상 중요한 주제입니다. 특히 명확한 에러 처리를 위해 종종 내장된 Error 클래스를 상속받아 사용자 정의(Custom) 에러 클래스를 만드는 경우가 많습니다.

하지만 이렇게 만든 커스텀 에러 클래스를 사용할 때 예상치 못한 문제가 발생하기도 합니다. 대표적인 예로, 열심히 만든 CustomError 클래스가 instanceof 검사를 통과하지 못하는 경우가 종종 있죠.

이번 포스팅에서는 이 문제의 원인인 "프로토타입 체인 문제"에 대해 알아보고, 명쾌한 해결책인 Object.setPrototypeOf 메서드를 활용하여 문제를 해결하는 방법을 함께 알아보겠습니다.


프로토타입 체인 문제란

자바스크립트는 프로토타입 기반의 언어로, 객체의 상속 관계를 프로토타입 체인(Prototype Chain)을 통해 정의합니다. 그런데, 일부 자바스크립트 엔진이나 TypeScript 컴파일 환경에서는 내장 클래스를 확장한 객체의 프로토타입 체인이 제대로 연결되지 않는 문제가 발생합니다.

이러한 문제가 발생하면, 우리가 흔히 사용하는 instanceof 연산이 제대로 동작하지 않을 수 있습니다. 즉, 분명히 CustomError로 만든 객체인데도 예상치 못한 결과가 나올 수 있습니다.

Object.setPrototypeOf
console.log(customError instanceof CustomError)

이 문제를 해결하는 방법 중 가장 간단하고 효과적인 방법이 바로 Object.setPrototypeOf 메서드를 이용하는 것입니다.


Object.setPrototypeOf를 사용하여 프로토타입 체인 문제 해결하기

Object.setPrototypeOf는 객체의 프로토타입을 명시적으로 다른 객체로 설정할 때 사용합니다. 이 메서드를 사용하면, 생성된 객체의 프로토타입을 정확히 원하는 프로토타입으로 설정할 수 있습니다.

아래의 예제 코드로 확인해 봅시다.

예제 코드

Object.setPrototypeOf
class CustomError extends Error {
  constructor(message: string) {
    super(message)
 
    // 프로토타입 체인을 정확하게 설정해주는 핵심 코드
    Object.setPrototypeOf(this, new.target.prototype)
  }
}
 
const errorInstance = new CustomError('문제가 발생했습니다!')
 
console.log(errorInstance instanceof CustomError) // true
console.log(errorInstance instanceof Error) // true
  • CustomError 클래스는 내장된 Error 클래스를 상속받아 커스텀 에러를 정의한 예입니다.
  • 생성자에서 super(message)로 기본적인 에러 메시지를 설정합니다.
  • 바로 아래의 Object.setPrototypeOf(this, new.target.prototype) 코드가 핵심입니다. 이 코드를 통해 현재 생성된 객체(this)의 프로토타입을 실제 호출된 생성자 클래스의 프로토타입으로 명확하게 설정합니다.
  • 이렇게 하면 instanceof 검사와 같은 프로토타입 기반 연산이 예상한 대로 동작하게 됩니다.

Object.setPrototypeOf를 사용할 때 주의점

Object.setPrototypeOf는 명시적으로 프로토타입 체인을 설정할 수 있게 해주는 매우 강력한 메서드입니다. 하지만 JavaScript 엔진 입장에서는 이 작업이 프로토타입 체인의 최적화를 방해하기 때문에 성능상 좋지 않은 영향을 미칠 수 있습니다.

특히, 빈번하게 호출되는 클래스의 생성자에서 이 작업을 수행하면 전체 애플리케이션의 성능이 떨어질 수 있습니다. 따라서 일반적인 클래스 구현에서는 이 메서드를 사용하는 것을 지양하고, 반드시 프로토타입 체인의 정확성이 중요한 에러 클래스와 같이 매우 제한적인 상황에서만 사용하는 것이 바람직합니다.


정리

TypeScript에서 Custom Error를 정의할 때 발생하는 프로토타입 체인 문제를 Object.setPrototypeOf 메서드를 통해 손쉽게 해결할 수 있습니다. 이 방법을 사용하면, 우리가 기대하는 대로 instanceof 검사가 제대로 작동하여 디버깅과 에러 처리를 명확히 할 수 있습니다.


참고