이 포스팅은 프로토타입 객체, 링크, 프로퍼티에 대한 설명은 물론, 이제까지 우리가 알고 있던 프로토타입 개념이 사실과 조금 다를 수 있다는 매운맛 정보가 담겨있습니다. (사실 안 매워용..ㅎㅎ)
1. 프로토타입 (feat. 매운 맛🔥)
자바스크립트는 프로토타입 기반 언어라고 불린다. 그런데 이 프로토타입은 무엇이며 어떻게 생성될까?
이 포스팅에서 자세히 알아보자 🙂
1) 프로토타입이란?
(1) 프로토타입은 무엇일까
- 자바스크립트에서는 객체를 생성할 때, 원형을 복사하는 방식을 취한다. (ex.
new Object()
) - 그리고 이 과정에서 객체에 프로토타입이 추가되는데, 우리는 프로토타입을 통해 객체 원형의 정보에 접근할 수 있게 된다.
- 만약 A객체를 기반으로 B객체를 생성했다면, B객체에서는 A객체의 정보에 접근할 수 있다는 말이다.
- A객체에
test()
가 있다면 B객체에서는 이 메소드를 접근해 사용할 수 있다. - 간단한 설명은 이 정도로 하고 예시와 함께 살펴보자!
(2) 프로토타입은 어떤 형태일까
- 아래 코드는 Object()를 사용해
obj
객체를 만드는 모습이다.
const obj = new Object();
- 이
obj
객체를 출력해보면 프로토타입([[Prototype]]
)이 존재한다.
obj
의 원형인Object
에서는hasOwnProperty()
가 있는데,obj
는 프로토타입이 존재하므로,- 이 프로토타입을 이용해 해당 함수에 접근할 수 있다.
그런데 앞서 본, 프로토타입 이미지를 보니, constructor, proto가 있던데, 이건 무엇일까?
이 두 개를 설명하기 위해서는 프로토타입 객체, 프로토타입 링크을 알아야 한다! 한 번 알아보자~
2) 프로토타입 객체? 프로토타입 링크?
(1) 프로토타입 객체
"프로토타입 객체는 자식에게 물려줄 정보를 담고 있다."
- 아래 코드는
Animal
객체를 이용해dog
인스턴스를 만든 모습이다. - 이 2줄에는 프로토타입 객체, 링크가 관여하는데 이 과정을 그림과 함께보자.
class Animal {}
const dog = new Animal();
- Animal()을 이용해
dog
인스턴스를 생성하고자 한다.
Animal()
을 사용해dog
인스턴스를 만든다.
이 과정에서Animal
의 정보가 담긴 프로토타입 객체가 관여하는데, 각각Animal
과dog
에 연결된다.
dog
인스턴스 생성 후 dog, dog의 원형과 연결된 프로토타입 객체는 무엇일까?
- 앞서 언급했듯이 js에서는 객체 생성시 원형 복사 방식을 취하며, 생성된 객체는 원형(부모) 정보를 가진다.
- 그렇다면 생성 객체는 부모의 어떤 정보를 가지고 있는 걸까?
- 그 정보는 바로 프로토타입 객체이다.
Animal
클래스 입장에서 보자!
Animal
클래스 입장에서 봤을 때,Animal
은 항상 자신을 복사하여 자식 객체(dog)를 만든다.- 그리고 자식 객체에게 정보를 상속시켜주기 위해 프로토타입 객체를 가지게 된다.
- 이 말은, 프로토타입 객체가 생성될 객체(자식)가 참조할 값을 지칭한다고 볼 수 있다.
- 결국, 모든 객체는 원형(부모)이 소유한 프로토타입 객체를 기반으로 생성된다.
아니 잠시만요? 그림을 보니까
__proto__
가 프로토타입과 연결되어 있던데 이건 뭐죠?
(2) 프로토타입 링크
"프로토타입 링크(
__proto__
)는 원형(상위)과의 연결고리 역할을 한다"
- 그림에서
dog
인스턴스의__proto__
와 프로토타입 객체의constructor
가 연결되어 있다.
그런데 이
__proto__
는 어떤 역할을 하며, 왜constructor
와 연결된걸까?
- 우리는 자식 객체에서 원형(부모)의 속성, 메소드를 접근할 수 있음을 알고 있다.
- 그럼 자식이 부모에게 접근하는 방법이 필요한 것이 아닌가? 그 방법은
__proto__
를 사용하는 것이다.
아래 그림은
Animal
에test()
가 있다고 가정하고,dog
에서test()
를 찾는 과정을 나타냈다.dog
에서test()
를 호출하고자 한다. 하지만dog
에는 해당 함수가 존재하지 않는다.
dog
는 부모의 정보를 접근하여test()
가 있는지 확인하고 싶다.- 이때 바로
__proto__
를 이용해 부모의 정보에 접근하는 것이다.
- 그런데 왜 프로토타입 객체가 아닌
constructor
와 연결된 걸까? - 그 이유는
construcutor
가 생성자 함수이기 때문이다. - 이 생성자 함수에는
dog
를 만들 때,Animal
을 기반으로dog
에서 사용할 정보를 생성한다. - 그러므로
test()
에 접근하기 위해서는construcutor
와 연결되어야 한다.
3) 내가 알던 프로토타입 개념과 다른데?
아니 잠시만요! 프로토타입 객체와 링크에 대해 알겠어요. 그런데, 제가 알고 있는 프로토타입은 객체에서 기본적으로 제공할 속성, 메소드를 저장한 공간인데요? 이상해요!
네! 이상할 수 있습니다. 왜냐하면 그 개념은 프로토타입 프로퍼티에 대한 설명이기 때문이죠!
대부분 프로토타입이라고 알고 있는 그 개념은 프로토타입 프로퍼티에 대한 설명입니다 🙂
(1) 사실 그건 프로토타입 프로퍼티 얘기!
- 프로토타입 객체의
constructor
에 프로토타입 프로퍼티가 있다. - 이 프로토타입 프로퍼티는 자식에게 물려줄 속성을 말한다.
- 자식 객체는 부모의 메소드, 속성에 접근할 수 있는데, 그 이유는 프로토타입 프로퍼티에 그 정보가 담겨 있기 때문이다.
- 결국, 프로토타입 프로퍼티로 인해 자식은 부모의 속성, 메소드를 사용할 수 있게 된다.
4) 프로토타입 예시를 보자
(1) 프로토타입 프로퍼티 예시
Animal
클래스는name
속성을 가지고 있는데,- 이 속성은 프로토타입 프로퍼티로서, 자식 객체에게 상속되는 값이 된다.
class Animal {
constructor({ name }) {
this.name = name; // 하위에게 물려줄 속성(prototype property)
}
}
- 만약 이
Animal
클래스를 사용해dog
객체를 생성한다면dog
에서name
을 사용할 수 있다.
(2) 프로토타입 링크 예시
- 앞선 예시를 다시 이용해보자.
class Animal {
constructor({ name }) {
this.name = name;
}
}
const dog = new Animal({ name: 'dog' });
__proto__
는 프로토타입 링크이며,dog
객체를 만들 때 사용한 원형에 대한 연결이다.dog
객체의 프로토타입 링크를 사용해age
속성을 추가하고,age
값을 12로 하면 어떻게 될까?
dog.__proto__.age = 12;
- 이 경우 age 속성이 추가되며, 값 또한 할당되어 있다.
- 이처럼 우리는 프로토타입 링크(
__proto__
)를 사용해 속성을 추가할 수 있게 된다.
(단, 기존에 존재하는 속성값을 프로토타입 링크로 수정할 수 없음)
오늘 우리는 프로토타입 객체, 링크, 프로퍼티에 대해 알아보았다.
프로토타입 객체는 생성될 객체(자식)가 참조할 값이며 프로토타입 링크는 상위와의 연결,
마지막으로 프로토타입 프로퍼티는 자식에게 물려줄 속성이다.
사실 개발을 할 때 프로토타입을 자주 사용하지는 않지만 (모듈을 만든다면 모를까) 개념정도는 알아두면 좋을 듯하다.
참고자료
'개발 기술 > 개발 이야기' 카테고리의 다른 글
promise와 async await의 차이점 (0) | 2021.11.17 |
---|---|
비동기 처리, promise와 async await (0) | 2021.11.15 |
프로토타입이란? (feat. 순한 맛 🌝) (0) | 2021.11.02 |
클래스(class)는 무엇인가 (0) | 2021.10.31 |
블록 스코프, 함수 스코프의 차이 (javascript) (0) | 2021.10.30 |
댓글