시스템아 미안해
Chapter 4 - Item 32. __proto__를 절대 수정하지 말라 본문
자바스크립트 엔진은 객체 생성 시 프로토타입 체인을 고정해놓고 내부 최적화를 적용한다.
객체를 처음 만들때 엔진은 그 객체의 Shape(히든 클래스)를 정의하는데,
이 Shape에 프로퍼티 위치, 타입, 프로토타입 체인 정보가 고정되는 방식이다.
덕분에 이후에 해당 객체의 프로퍼티를 접근할 때, 엔진은 “이 프로퍼티는 메모리 어디에 있다”를 미리 알고 바로 접근할 수 있다.
객체의 프로토타입 체인을 __proto__나 Object.setPrototypeOf를 사용하여 바꾸면,
엔진은 기존 Shape가 더 이상 유효하지 않다고 판단하여
기존 최적화가 전부 무효화되고, 히든 클래스 전환(Transition) 발생하며, JIT 재컴파일 필요하다.
이런 재컴파일 과정이 잦아지면 메모리 사용량이 증가하고, 접근 속도가 수십 배 느려질 수 있다.
const a = { x: 1 };
const b = { y: 2 };
// 절대 이렇게 하지 말 것
b.__proto__ = a;
// 또는 이렇게도 하지 말 것
Object.setPrototypeOf(b, a);
위 코드는 b의 프로토타입을 바꿔서 a의 속성을 물려받게 하지만, 엔진 최적화를 깨버린다.
프로토타입을 바꾸고 싶다면 객체 생성 시점에 Object.create 사용.
const proto = { x: 1 };
const obj = Object.create(proto);
obj.y = 2;
이렇게 하면 엔진이 처음부터 proto를 기반으로 최적화 가능하다.
- __proto__ 수정은 디버깅 목적이거나 레거시 코드 유지 외에는 쓰지 말 것.
- 새 객체를 만드는 그 타이밍에 프로토타입을 지정하는 것이 훨씬 안전하고 성능도 좋음.
ES6에서 __proto__가 공식 표준에 포함되었지만, 성능 문제와 유지보수성을 고려해 여전히 수정은 금지된다.
Object.setPrototypeOf 역시 수정 동작이므로 동일한 주의를 요하고,
실무에서 Object.create로 설계 시점에 프로토타입을 확정하는 패턴을 사용할것을 권한다.
'책 > Effective JavaScript' 카테고리의 다른 글
| Chapter 4 - Item 34. 메서드는 프로토타입에 저장하라 (2) | 2025.08.10 |
|---|---|
| Chapter 4 - Item 33. 생성자를 new에 의존하지 않게 만들기 (0) | 2025.08.10 |
| Chapter 4 - Item 31. Object.getPrototypeOf를 __proto__ 대신 사용하라 (0) | 2025.08.10 |
| Chapter 4 - Item 30. prototype, getPrototypeOf, __proto__ 차이를 이해하라 (1) | 2025.08.10 |
| Chapter 3 - Item 29. 비표준 스택 검사 속성 사용을 피하라 (1) | 2025.08.10 |