[JS] 프로토타입(Prototype) #2

김민규·2022년 9월 7일
0

자바스크립트

목록 보기
5/7
post-thumbnail

참고한 페이지
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를 쓰면 이런 실수를 방지할 수 있을 겁니다.

this

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...in

for(prop in bob) console.log(prop, bob.hasOwnProperty(prop));

for in은 bob의 프로토타입 속성까지 순회합니다. hasOwnProperty메서드는 bob의 속성인 경우 true, 프로토타입 속성이면 false를 반환하죠. 결과는 다음과 같습니다.

name true
eat false
sleep false

디폴트 prototype과 constructor

모든 함수는 prototype을 기본 속성으로 가집니다. 디폴트 prototype은 constructor 속성 하나만 가지는 prototype입니다. constructor는 함수 자신을 가리킵니다.

function f () {};
f.prototype.constructor === f; // true

constructor는 함수 자신을 가리킨다고 했으니, constructor를 사용하여 새 객체를 만들 수 있겠죠.

new f.prototype.constructor();
profile
점점 더 좋아지고 있습니다

0개의 댓글