정의
자바스크립트의 모든 객체는 자신의 원형(Prototype)이 되는 객체를 가지며 이를 프로토타입이라 한다.
보이지 않는 속성인 [[Prototype]]이 자신의 프로토타입 객체를 참조한다.
이를 __proto__라는 속성으로 참조할 수 있으나 이는 비표준이고 모든 브라우저에서 동작하지 않기에 실사용은 지양하자.
.prototype과 [[Prototype]]
모든 객체는 은닉 속성인 [[Prototype]]을 갖는데 특별히 함수 객체는 접근할 수 있는 속성인 prototype을 갖는다.
프로토타입이 햇갈리는 이유가 여기서 나온다.
이름이 비슷해 관계를 명확하게 파악하기 쉽지 않다.
[[Prototype]] 이란?
자신의 프로토타입 객체를 참조하는 속성
.prototype 이란?
new 연산자로 자신을 생성자 함수로 사용한 경우, 그것으로 만들어진 새로운 객체의 [[Prototype]]이 참조하는 값
function Func() {}
var a = new Func();
사진에서 constructor는 모든 .prototype객체의 속성에 있는 것으로 실제 객체를 참조한다.
위에서 Func를 가리키는 것이다.
Func.prototype의 [[Prototype]]이 Object.prototype으로 연결되는데 이는 모든 객체의 프로토타입 객체로 마지막으로 연결되는 프로토타입 객체이다.
정리하자면
- new 연산자로 새로운 객체 a를 생성하면, a의 프로토타입 객체는 생성자 함수로 사용한 Func의 속성인 Func.prototype이 된다.
- Func.prototype은 constructor 속성을 갖으며, 실제 객체 Func를 가리킨다.
- Func.prototype 또한 객체이므로 [[Prototype]]을 갖고있는 모든 객체의 원형이 되는 객체인 Object.prototype을 가리킨다.
프로토타입 체인
어떤 객체의 프로퍼티를 참조하거나 값을 할당할 때 해당 객체에 프로퍼티가 없을 경우, 그 객체의 프로토타입 객체를 연쇄적으로 보면서 프로퍼티를 찾는 방식을 프로토타입 체인이라 한다.
단, 참조할 때와 값을 할당할 때의 메커니즘이 다르다.
프로퍼티를 참조할 때
- 찾고자 하는 프로퍼티가 객체에 존재하면 사용한다.
- 없으면 [[Prototype]] 링크를 타고 끝까지 올라면서 해당 프로퍼티를 찾는다.
- 찾으면 그 값을 사용, 없으면 undefined 반환
프로퍼티에 앖을 할당할 때
- 찾고자 하는 프로퍼티가 객체에 존재하면 값을 바꾼다.
- 프로퍼티가 없고 [[Prototype]] 링크를 타고 올라가서 해당 프로퍼티를 찾았을 경우
- 그 프로퍼티가 변경가능한 값(writable : true) 라면 새로운 직속 프로퍼티를 할당해 사우이 프로퍼티가 가려지는 현상이 발생
- 그 프로퍼티가 변경 불가능한 값(writable : false) 라면 비엄격 모드에선 무시되고 엄격 모드에서는 에러 발생
- 해당 프로퍼티가 세터(setter)인 경우, 이 세터가 호출되고 가려짐이 발생하지 않는다.
가려짐이란? 상위 프로토타입 객체에 동일한 이름의 프로퍼티가 있는 경우, 하위 객체의 프로퍼티에 의해 가려지즌 현상
function Func() {}
Func.prototype.num = 2;
var a = new Func();
a.num = 1;
console.log(a.num); // 1
위의 코드에서 객체 a의 프로토타입 객체인 Func.prototype에 num이 있지만 a.num = 1 로 인해 가려짐 현상이 발생해 1을 출력한다.
function Func() {}
Object.defineProperty(Func.prototype, "num", {
value: 2,
writable: false
})
var a = new Func();
a.num = 1; // 무시됨
console.log(a.num); // 2
하지만, defineProperty()를 사용하면 변경불가능한 프로퍼티로 만들면 비엄격모드에서 무시되어 2를 출력한다.
참고 링크
- https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/javascript/prototype.md
- https://poiemaweb.com/js-prototype
'JavaScript > Javascript' 카테고리의 다른 글
== VS === (느슨한 동등 비교 VS 엄격한 동등 비교) (1) | 2023.10.14 |
---|---|
자바스크립트 비동기와 이벤트 루프 (1) | 2023.10.07 |
Javascript의 메모리누수와 가비지 컬렉션 (0) | 2023.10.06 |
콜 스택(Call stack)과 힙(Heap) (0) | 2023.10.06 |
IIFE (Immediately Invoked Function Expression, 즉시 실행 함수 표현식) (0) | 2023.10.04 |