자바스크립트/모던 자바스크립트

모던 자바스크립트, 프로토타입 얻기 설정하기 (getPrototypeOf, setPrototypeOf)

Jake Seo 2023. 1. 24. 23:28

객체 프로토타입 얻기와 설정하기

  • Object.getPrototypeOf(o) 를 통해 객체의 프로토타입을 얻을 수 있다.
    • ES5의 obj.__proto__ 와 같다.
  • Object.setPrototypeOf(obj, proto) 를 통해 객체의 프로토타입을 설정할 수 있다.
    • ES5의 obj.__proto__ = proto 와 같다.

ES5 예제 소스코드

const proto = {
  greet() {
    console.log(`proto greet, name = ${this.name}`);
  },
};

const obj = Object.create(proto);

console.log(obj.__proto__); // {greet: ƒ}
obj.name = "Joe";
obj.greet(); // proto greet, name = Joe
  • 기존의 __proto__ 는 deprecated 되었으므로, 더이상 사용하지 않는 것이 좋다.

ES6 이후 예제 소스코드

const proto = {
  greet() {
    console.log(`proto greet, name = ${this.name}`);
  },
};

const obj = Object.setPrototypeOf({}, proto);

console.log(Object.getPrototypeOf(obj)); // {greet: ƒ}
obj.name = "Joe";
obj.greet(); // proto greet, name = Joe
  • ES5 에서는 Object.create() 를 사용하거나 obj.__proto__ 에 직접 할당해야 했는데 ES6에서 공식적인 스펙이 생겼다.
  • Object.setPrototypeOf(obj, proto) 는 기존의 obj.__proto__ = proto 를 대체한다.

공식 스펙이 되었지만, 아이러니하게도 공식문서에서는 기존 객체의 프로토타입을 변경하면 퍼포먼스에 안좋을 수 있으니 퍼포먼스를 고려한다면, Object.create() 로 새로운 프로토타입을 가진 새로운 객체를 생성하라고 경고하고 있다.

__proto__ 를 사용하면 안되는 이유

  • 브라우저가 아닌 자바스크립트 엔진에서는 공식 스펙이 아니다.
    • 물론 지원할 수도 있다.
  • __proto__Object.prototype 에 의해 정의된 접근자 속성이어서 객체가 Object.prototype 을 상속하지 않았다면 사용할 수 없다.

Object 를 상속하지 않고 __proto__ 를 사용하는 경우

const proto = {
  hello() {
    console.log("hello");
  },
};

const obj = Object.create(null);

obj.__proto__ = proto;

console.log(obj.hello()); // Uncaught TypeError: obj.hello is not a function
  • 메서드 호출 시 에러가 난다.

Object 를 상속하지 않았지만, Object.setPrototypeOf() 를 사용하는 경우

const proto = {
  hello() {
    console.log("hello");
  },
};

const obj = Object.create(null);

Object.setPrototypeOf(obj, proto);

console.log(obj.hello()); // hello
  • Object 를 상속하지 않았지만, 메서드 호출 시 에러가 발생하지 않는다.
반응형