182일차 - prototype

JavaScript는 프로토타입 기반 언어

이하 자료는 MDN에서 참고했다.

JavScript(이하 JS)는 흔히 프로토타입 기반 언어(prototype-based language)라 불린다.

이는 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object) 를 가진다는 의미이다.
프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상복 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지 이다. 이를 프로토타입 체인(prototype chain) 이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간이다.

정확히 말하자면 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype 이라는 속성에 정의되어 있다.

JS에서는 객체 인스턴스와 프로토타입 간에 연결이 구성되며 이 연결을 따라 프로토 타입 체인을 타고 올라가며 속성과 메소드를 탐색한다.

prototype을 확인하는법

이하 자료는 PoiemWeb에서 참고했다.

const person = {
    name: 'chan',
    age: 27
};

console.log(person.hasOwnProperty('name')); // true

console.dir(person);

자바스크립트의 모든 객체는 [[Prototype]]이라는 인터널 슬롯(internal slot)를 가진다. [[Prototype]]의 값은 null 또는 객체이며 상속을 구현하는데 사용된다.

[[Prototype]]의 값은 Prototype(프로토타입) 객체이며 __proto__로 접근 할 수 있다. __proto__프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf가 호출되어 프로토타입 객체를 반환한다.

console.dir(person.__proto__);

객체를 생성할 때 프로토타입은 결정된다. 결정된 프로토타입 객체는 다른 임의의 객체로 변경할 수 있다. 이 것은 부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미한다. 이러한 특징을 활용하여 객체의 상속을 구현할 수 있다.

Prototype chain

자바스크립트는 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티 또는 메소드가 없으면 [[Prototype]]이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다.
이것을 프로토타입 체인이라고 한다.

위의 예로 다시 돌아가면 person객체는 hasOwnProperty메소드를 가지고 있지 않으므로 에러가 발생하여야 하지만 정상적으로 결과가 출력되었다. 이는 person 객체의 [[Prototype]]이 가리키는 링크로 따라가서 person객체의 부모 역할을 하는 프로토타입 객체 (Object.prototype)의 메소드 hasOwnProperty)를 호출하였기 때문에 가능한 것이다.

const person = {
    name: 'chan',
    age: 27
};

console.log(person.hasOwnProperty('name')); // true

Number, String, Boolean 객체

그럼 객체가 아닌 원시타입 Number, String, Boolean은 어떻게 아래와 같은 Prototype메소드들이 존재하는 것일까?

사실 Number, String, Boolean에는 각각 대응하는 객체 타입 Number, String, Boolean이 존재한다.

JS는 일시적인 Number, String, Boolean객체를 만든다. 그 임시객체에는 toString()등의 함수가 들어있다. JS는 함수를 호출하는 즉시 이 임시 객체를 파괴한다.

이는 아래와 같이 확인해 볼 수 있다.

const name - 'chan';
name.age = 27; // 객체의 프로퍼티 추가 방식을 사용했는데 에러가 나지 않는다.
name.age; // undefined

문자열 name에 프로퍼티를 할당하는 것처럼 보이지만, 프로퍼티에 접근을 하려하자 undefined가 출력된다. 이는 일시적인 String 객체에 프로퍼티를 할당한 것이다. 임시 객체는 즉시 파괴되므로 name.ageundefined이다.

참고자료

러닝자바스크립트 - 저자)이선 브라운
PoiemaWeb - Prototpye
Jewoo.Song - 프로토타입과 프로토타입 체인
MDN - Object prototypes

사진출처 - MDN

좋은 웹페이지 즐겨찾기