16장 프로토타입을 공부하던중 이 개념이 너무 헷갈려서 오늘은 번외로 __proto__
, [[Prototype]]
, prototype
이라는 녀석ㅅㄲ들을 알아보자 ❗
오승환 님의 medium 블로그를 참고했다 ❗
오승환 / medium / 프로토타입 이해하기
예시를 통해 바로 알아보자.
function Person() {
this.eyes = 2;
this.nose = 1;
}
var kim = new Person();
var park = new Person();
console.log(kim.eyes); // 2
console.log(kim.nose); // 2
console.log(park.eyes); // 2
console.log(park.nose); // 1
위 코드를 보면 kim
과 park
의 eyes
와 nose
가 중복으로 할당 되는것을 확인할 수 있다. 우리가 원하는 결과를 도출하는데 문제는 없지만 객체가 많아진다면 상당한 메모리 낭비를 가져올 수 있다.
우리는 prototype
을 이용하여 이 문제를 간단히 해결할 수 있다.
function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
var kim = new Person();
var park = new Person();
console.log(kim.eyes); // 2
위 코드를 보면 우리는 Person.prototype
이라는 객체에 eyes
, nose
라는 프로퍼티를 주었다. 그러고나서 Person.prototype
을 가져다 사용했을 뿐이다.
그러면 여기서 Person.ptototype
은 어디서 튀어나온 녀석인가 ❓
우리는 객체는 함수로 인해 생성된다는 것을 알고 있어야한다.
var obj = {};
그럼 위와 같이 객체 리터럴로 선언된 객체도 함수로 인해 생성 된것인가? 라고 묻는다면
var obj = new Object();
위 코드처럼 JS에서 기본적으로 제공하는 Object
함수로 인해 생성됐다고 할 수 있다.
그래서 prototype
은 어디서 튀어나온거냐 뭐 어쩌라는 거냐고 다시 묻는다면 함수는 정의될때 2가지 일을 동시에 수행한다고 답할것이다.
✅ 해당 함수에 Constructor
자격 부여
Constructor
자격이 부여되면 new
키워드를 통해 객체를 만들어 낼 수 있다.
✅ 해당 함수의 Prototype Object
생성 및 연결
함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object
도 같이 생성이 된다.
그리고 생성된 함수는 prototype
이라는 속성을 통해 Prototype Object
에 접근할 수 있다. Prototype Object
는 일반적인 객체와 같으며 기본적인 속성으로 constructor
와 __proto__
를 가지고 있다.
콘솔창으로 찍어보면 위 그림대로 이어져 있는 것을 확인할 수 있다.
내가 제일 헷갈린 부분이였다. 도대체 prototype
은 어떻게 생겨먹은 놈이 어디서 갑자기 튀어 나왔는지 prototype
은 생성자 함수 내부에 있는건지 어디에 위치 했는지, 이에 대답은 ❓
아예 별개의 객체로 같이 생성된다는 것 ❗❗
이거 이해하는데 몇날 몇일이 걸렸다 tlqkf 프로토 ㅅㄲ들
그렇다면 __proto__
에 대해서 알아도록 하자.
위에서 봤던 두번째 예시를 기억하는가
console.log(kim.eyes) // 2
위와 같은 코드가 있었는데 kim
객체에는 eyes
라는 속성이 없는데 어떻게 참조 한 것일까?
바로 __proto__
가 참조를 가능하게 해준다. prototype
과는 달리 __proto__
는 모든 객체들이 가지고 있는 속성이며 객체가 생성될 대 조상인 상위 함수의 Prototype Object
를 가르키게 된다.
즉, kim
객체는 Person
함수로부터 생성됐으니 Person
함수의 Prototype Object
를 가르키고 있는것이다.
kim
이 Person Prototype Object
를 가르키는 것처럼 하위 객체들은 상위 프로토타입을 체인처럼 연결하여 참조하는 속성을 찾는다.
[[Prototype]]
이란 생성자 함수가 생성 될때 생성되는 prototype
이 위치한 내부 슬롯이며 개발자가 의도적으로 접근이 불가 하기 때문에 __proto__
접근자 프로퍼티를 사용하여 간접적으로 접근한다.
활용할 수 있을 만큼 이해 하진 못했지만, 이 ㅅㄲ들 때문에 왔던 JS 권태기가 어느정도 회복 된 나에게 박수 ~ 😊