__proto__
__proto__
는 사실 더 이상 권장되지 않는 기능이다. 최근 관련된 웹 표준에서 사라졌을 수 있으며, 혹은 사라지는 중일 수 있다. 물론, 호환성을 위해 아직 없애지 않는 브라우저가 대부분이긴 할 것이다. __proto__
를 사용하기보다는 가능하다면 존재하는 코드를 업데이트하여 __proto__
의 사용을 자제하자.
호환성 목록에서 어떤 환경에서 호환하지 않는지 볼 수 있다.
현대식 자바스크립트에서 프로토타입을 다루기 위한 모던한 메소드들이 있다.
Object.create(proto, [descriptors])
: [[Prototype]]
이 proto
를 참조하는 빈 객체를 만든다. 이 때, 프로퍼티 설명자도 추가로 넘길 수 있다.Object.getPrototypeOf(obj)
: obj
의 [[Prototype]]
을 반환한다.Object.setPrototypeOf(obj, proto)
: obj
의 [[Prototype]]
이 proto
가 되도록 설정한다.앞으로는
__proto__
대신 위의 메소드를 이용해서 프로토타입 관련 기능을 작성하자.
const module = {
detach: true,
attach: true
}
const monitor = Object.create(module);
alert(`monitor.detach = ${monitor.detach}`); // true
alert(`monitor.attach = ${monitor.attach}`); // true
alert(Object.getPrototypeOf(monitor) === module); // true
// 아이맥의 모니터라면?
Object.setPrototypeOf(monitor, {detach: false, attach: false});
alert(`monitor.detach = ${monitor.detach}`); // false
alert(`monitor.attach = ${monitor.attach}`); // false
alert(Object.getPrototypeOf(monitor) === module); // false
위와 같이 활용해볼 수 있다.
간단하게 설명자로 프로퍼티 플래그를 건드려보고 출력해본 결과이다.
일단 모던 프로토타입 메서드를 어떻게 사용하는지를 먼저 배워봤는데, 그렇다면 기존에 __proto__
도 엄청 편했던 것 같은데, 뭐가 문제여서 모던 프로토타입 메서드를 권장하는 것일까?
Object.create()
가 등장하여 프로토타입이 설정된 객체를 만들어낼 수 있게 되었다.__proto__
가 등장하여 마음대로 프로토타입을 얻거나 설정할 수 있게 되었다.getPrototypeOf
와 setPrototypeOf
가 표준에 추가되었다.그러나 여전히
Object.setPrototypeOf
로도 마음대로 프로토타입을 바꾸게 되면 자바스크립트 엔진의 최적화가 저해된다.
__proto__
를 키로 이용하여 값을 넣게 되면 값이 제대로 들어가지 않는다.const obj = {};
const key = prompt("사용할 key를 입력", "__proto__");
obj[key] = "value";
alert(obj[key]);
위의 코드가 제대로 작동하지 않는 이유는 __proto__
에는 객체만 들어갈 수 있기 때문이다. 그래서 [object Object]
가 나오는 것이다.