참고한 페이지
JAVASCRIPT.INFO 프로토타입 상속
JAVASCRIPT.INFO 프로토타입 메서드와__proto__
가 없는 객체
__proto__
는 구식?__proto__
는 객체 속성인 [[prototype]]의 getter, setter입니다. 생성자 함수의 prototype 속성에서 왔죠.
프로토타입을 지정하는 보다 모던한 방식으로 Object.getPrototypeOf, Object.setPrototypeOf 메서드가 있습니다. 그냥 __proto__
를 써도 될 텐데, 새 방식이 등장한 이유가 뭘까요?
const o = {};
const key = '__proto__';
o[key] = '이 값은 출력되지 않습니다.';
console.log(o[key]);
위 코드를 실행해 보세요. __proto__
에 문자열을 넣을 수 없다는 것을 알 수 있습니다. null 또는 객체만 허용하죠. 이건 문제가 아닙니다.
const o = {};
const key = '__proto__';
o[key].toString = () => { console.log('changed!'); };
o.toString(); // changed!
실수로 프로토타입 자체 또는 속성을 바꿀 수 있겠죠. 이 경우 프로토타입을 가지는 객체들이 영향을 받아 의도치 않은 문제가 생길 수 있을 겁니다.
Object.getPrototypeOf, Object.setPrototypeOf를 쓰면 이런 실수를 방지할 수 있을 겁니다.
const person = {
eat() {
if (!this.full) {
this.full = true;
return;
}
console.log('그만 먹어!');
},
sleep() {
if (!this.full) return;
console.log('먹고 바로 자려고?');
},
};
const bob = {
name: 'Bob',
__proto__: person,
};
bob.eat();
bob.eat(); // 그만 먹어!
bob.sleep(); // 먹고 바로 자려고?
this.full에서 this가 가리키는 것은 bob일까요? person일까요? 답을 정했으면, 이어서 다음 코드를 실행해 보세요.
console.log(bob.full); // true
console.log(person.full); // ?
for(prop in bob) console.log(prop, bob.hasOwnProperty(prop));
for in은 bob의 프로토타입 속성까지 순회합니다. hasOwnProperty메서드는 bob의 속성인 경우 true, 프로토타입 속성이면 false를 반환하죠. 결과는 다음과 같습니다.
name true
eat false
sleep false
모든 함수는 prototype을 기본 속성으로 가집니다. 디폴트 prototype은 constructor 속성 하나만 가지는 prototype입니다. constructor는 함수 자신을 가리킵니다.
function f () {};
f.prototype.constructor === f; // true
constructor는 함수 자신을 가리킨다고 했으니, constructor를 사용하여 새 객체를 만들 수 있겠죠.
new f.prototype.constructor();