대망의 ProtoType이다. 대부분 학원 출신 개발자들은 Java를 통해 개발에 입문을 하는 케이스가 많다보니, 아무래도 Class 기반의 객체를 익숙하게 여길텐데, 놀랍게도 이 방식대로 자바스크립트에 접근했다가는 머리통이 아픈 순간이 찾아온다.
'아니 뭔소리냐? 자바스크립트도 class라는 문법이 있는데, class기반이 아니라니?' 라고 할 수도 있는데, 그건 ES6 시점에서 문법이 추가된거고, 또한 저 class역시 자바에서 말하는 class와는 다르다. 자 그럼 이 prototype이라는게 뭔지 한번 시작해보도록 하자.
1. ProtoType?
자바스크립트의 요소들은 대부분 객체다. Object 뿐만 아니라 String, Array, Number.. 등등 모두 객체인데, 기존의 자바에서 알고 있던 객체들과는 다르게 자바스크립트의 객체들은 상당히 특이한 게 있다. 따로 상속같은걸 하지 않았음에도 모든 객체들이 부모객체를 기억하고 연결 되어있다는 것이다.
이게 뭔소린지 한번 살펴보자.
const obj = {
name: 'ota',
age: 12
} // 객체 만들었음, 따로 안에 Method는 선언하지 않았음.
console.log(obj.hasOwnProperty('name')); // 하지만 없던 Method가 생겼음.
위의 코드를 보면 알 수 있다시피, 우리는 객체 내부에 Method를 선언하지 않았음에도 불구하고 hasOwnProperty()라는 Method를 사용할 수가 있다. 이게 과연 어디서 튀어나온걸까? 그게 바로 ProtoType이다.
자바스크립트에서 모든 객체는 앞에서 말했듯 부모와 연결이 되어있다. 그리고 그 부모들을 ProtoType이라고 부르게 된다.
내가 만든 obj라는 객체는 Object라는 자바스크립트 내부적으로 만들어져있는 ProtoType을 부모로 가지고 있고, 그 자바스크립트 내부에서 만들어진 Object가 가진 hasOwnProperty()라는 Method를 탐색해 사용할 수가 있는거다.
그래서 모든 Object의 자식들은 이 Object protoType을 가지고 있을테니 모든 자식인스턴스들에게 공통의 프로퍼티나 Method를 제공하고 싶을 때 사용하게 된다.
2. 함수의 Prototype..?
우리는 익히 알고 있다. 자바스크립트에서 함수는 진짜 기가 막히게 특이한 놈이란걸, 언제나 예외의 대상에 들어가 있다. 좋은거 다함. 이번에도 함수는 특이한게 있다. 모든 객체들은 [[Prototype]] 이라는 어려운 말로 하면 인터널 슬롯이란걸 가지는데, 그냥 단순하게 [[Prototype]]을 가지고, __proto__라는 프로퍼티를 통해 접근할 수있다. 정도로만 생각하고 있어도 될 것 같다. 허나 Prototype이라는 이름의 프로퍼티를 가지고 있는건 딱 함수 뿐이다. 이게 도대체 왜 있는가?
정답은 함수의 사용방법 중 하나인 생성자 함수 때문이다.
function Car(engine, wheel) {
this.engine = engine;
this.wheel = wheel;
}
const car = new Car(engine, wheel)
이전에도 설명했지만 이렇게 생긴게 생성자 함수인데, 이 생성자 함수는 객체 인스턴스를 만들때 사용하게 된다. 이 인스턴스를 위해 Prototype 프로퍼티가 존재한다고 생각하면 된다. 앞에서 말했듯이 모든 객체는 [[Prototype]] 이런 모양의 인터널 슬롯을 가지고 있는데 여기는 객체의 부모정보가 있다. 그래서 인스턴스를 만들어주면서 저 인터널 슬롯에 부모를 넣어주기 위해서 존재하는 것임. 결과적으로 위의 코드를 예로 들었을때 car라는 인스턴스가 가진 인터널 슬롯은 Object.prototype 일 것이고, 당연히 함수 자체의 인터널 슬롯 안에는 Function.prototype이 들어가 있을 것이다.
3. Constructor
자 그러면 한가지 생각이 든다. '아니, 근데 car라는 인스턴스를 만들어준건 Car()인데, 이 둘은 아무런 관계가 없어? ' 라는 생각이다. 이걸 위해서 준비되어있는게 constructor다. 객체는 constructor라는 프로퍼티를 가지고 있는데, 이건 지금 이 객체를 만들어준 녀석을 담고 있는 곳이다. 그러니 car.constructor === Car 가 성립한다고 보면 되겠다.
글이 길어지니 다음 글에서 Prototype 체인 까지 한번 다뤄보겠다.
'Dev > JavaScript' 카테고리의 다른 글
[JavaScript] Wrapper Object (0) | 2023.07.13 |
---|---|
[JavaScript] ProtoType (2) (0) | 2023.07.13 |
[JavaScript] this (0) | 2023.06.29 |
[JavaScript] 생성자 함수 (0) | 2023.06.29 |
[JavaScript] 정규표현식 (0) | 2023.06.28 |