Skip to content

JavaScript:Object

Object prorotype

JavaScript에서 모든 객체들은 Object의 자손입니다. 모든 객체는 Object.prototype으로부터 메서드와 속성을 상속하는데, 나중에 덮어 쓸(Overriding) 수도 있습니다.

Object.prototype.toString()
객체의 문자열 표현을 반환합니다.

defineProperty

Object.defineProperty() 정적 메서드는 객체에 직접 새로운 속성을 정의하거나 이미 존재하는 속성을 수정한 후, 그 객체를 반환합니다.

Key/Values/Entries

  • Object.keys, values, entries
  • Object.keys(obj) – 키가 담긴 배열을 반환합니다.
  • Object.values(obj) – 값이 담긴 배열을 반환합니다.
  • Object.entries(obj)[key, value] 쌍이 담긴 배열을 반환합니다.

Troubleshooting

Object prototype mismatch

다음과 같은 클래스가 있을 때,

class CustomError extends Error { 
    constructor(message: string) {
      super(`Lorem "${message}" ipsum dolor.`);
      this.name = 'CustomError';
    }
}
throw new CustomError('foo'); 

예상되는 출력은 Uncaught CustomError: Lorem "foo" ipsum dolor. 이지만, 실제 출력은 Uncaught Error: Lorem "foo" ipsum dolor. 이다.

이 경우, tsconfig.json에서 targetes5 되어있지 않나 확인해 보자. ES5에서 관련 이슈가 있다. 이를 해결하기 위해, 생성자에서 super(...) 호출 직후 프로토타입을 수동으로 조정해야 한다.

class CustomError extends Error {
  constructor(message?: string) {
    // 'Error' breaks prototype chain here
    super(message); 

    // restore prototype chain
    const actualProto = new.target.prototype;

    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(this, actualProto);
    } else {
      this.__proto__ = actualProto;
    }
  }
}
  • Object.setPrototypeOf를 지원하지 않는 런타임의 경우 대신 __proto__를 사용하도록 조정해야 한다.
  • 불행히도 이러한 해결 방법은 Internet Explorer 10 및 이전 버전에서 작동하지 않습니다. 프로토타입에서 인스턴스 자체로 메소드를 수동으로 복사할 수 있지만(i.e. FooError.prototype onto this) 프로토타입 체인 자체는 수정할 수 없습니다.
  • 이렇게 수정한 모든 하위 클래스도 수동으로 프로토타입을 설정해야 합니다. <- (가장 큰 문제)

차라리 간단하게. tsconfig.json의 target 버전을 높이자. 나는 esnext로 했다. 어차피 babel이 호환성 작업 알아서 해주겠지...

See also

Favorite site