[JS] 자바스크립트 딥다이브 - 16. 프로퍼티 어트리뷰트

Juhyang·2022년 2월 28일
0

Q. [[prototype]]을 접근하려면 왜 __proto__ 를 쓸까? __proto__ 가 좋은 방법일까요?

정답은 아니다!
예전에 표준화 되기 전에 브라우저가 자기들 맘대로 __proto__ 으로 접근되게 해놨다. (즉 비표준 방법 이었음.) 브라우저 대부분 이렇게 접근되어서 결국 es6가 표준화를 해주긴 했으나, 더이상 추천되지 않는 방법이라고 한다. (없앨 예정의 방법)

그래서 프로토타입 내부 슬롯을 접근하는 방법의 권장 사항으로는
이제 object.getProtoTypeOf() 를 사용하는게 좋다.

const obj = {}

console.dir(obj) 
// [[Prototype]]: Object

o.[[prototype]] 
// Syntax error

o[[prototype]]
// Syntax error

obj.__proto__
/* {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, 
hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} */

Object.getPrototypeOf(obj)
/* {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, 
hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} */
  1. 아래 코드가 왜 undefinde 일까요? 이유와 잘 나올 수 있는 방안 설명하기
const neo = new Person('neo');
neo.__proto__.getName(); // undefined

Person.prototype === neo.__proto__ // true

위의 getName() 메서드 호출 결과가 undefined 인 점을 주목해야 합니다. 에러는 발생하지 않았으니, 호출할 수 있는 함수이긴 합니다. 만약 함수가 아니었다면 TypeError 가 발생했겠죠.

getName 은 this._name 을 리턴하도록 되어있는데, 어떤 함수를 '메서드로서' 호출할 때는 메서드명 바로 앞의 객체가 곧 this 입니다. 따라서 여기선 neo.proto.getName() 내부에서의 this 가 neo 가 아닌 neo.proto 객체가 되어 undefined 를 리턴했습니다. this 에 바인딩된 대상이 잘못되었다는 것입니다.

해결 방법 1

neo.__proto__._name = 'proto neo';

위처럼 proto 객체에 name 프로퍼티를 강제 주입하면, getName() 메서드 호출 결과가 원하는 대로 출력됩니다.

해결 방법 2

const neo = new Person('neo');
neo.getName();

사실 프로퍼티 자체가 생략될 수 있는 함수임.


참고자료
인프런 - 자바스크립트 딥다이브
js - 프로토타입에 대한 이해

profile
kurly - commerce web development

0개의 댓글