자바스크립트를 이루고 있는 것은 거의 객체이다.
우리가 자바스크립트에서 '함수'라고 부르는 것도 결국에 "함수라는 객체"인 것이며,
이 점을 알고보면 "함수는 일급객체이다" 라는 기본 전제에서, 왜 "객체"라고 했는지도 이해가 간다.
즉, 함수는 일반 객체들과 달리 함수만의 특성이 추가된 객체의 한 종류인 것이다.
(거의 모든 것은 객체이며) 모든 객체는 모두 어떤 객체의 파생객체이다.
자바스크립트는 어떤 본보기 조상님 객체가 심어져있고,
이용자는 그 객체에서 파생되어 똑같은 성질등을 공유하는 객체를 이용해서 개발을 하는 것이다.
예를들어 함수의 경우에서,
실제로 우리가 정의하는 모든 함수 객체들은, Function이라는 고인물 조상님 객체의 파생객체이다.
즉, 내가 만든 임의의 함수 foo의 역시 Function()이란 객체의 파생 객체이다.
(그리고 이 Function은 당연히 처음 자바스크립트 설계자가 만든 것이고)
prototype이란
prototype이란 자바스크립트에서 상속을하기 위한 메커니즘이다.
함수 객체를 정의하는 순간 prototype객체가 생긴다.
function Animal(){}
Animal.prototype
//{constructor: f}
위의 코드에서 따로 prototype이라는 객체를 만들지도 않았는데, Animal.prototype이 조회된다.
왜 이럴까?
우리가 Animal이라는 객체를 만들면 이 Animal만 단순히 생성되는게 아니라, prototype 객체도 그림자처럼 슬그머니 생성된다.
이 Animal 객체와 Animal의 prototype객체는 서로서로 연결되어 있다.
때문에 다름과 같은 문장은 true가 된다.
function Animal(){}
Animal.prototype.constructor === Animal //true
객체를 이용해 새로운 객체를 생성하면 __proto__로 연결된다.
그럼 이 만들어진 Animal함수 객체를 new를 이용해 인스턴스 객체로 가져와보자.
만들어진 인스턴스 객체들은 .prototype은 생성되지 않아 undefined가 뜨지만,
__proto__로 Animal객체의 prototype 객체와 연결되어 있음을 확인할 수 있다.
function Animal(){}
Animal.prototype; // {constructor: ƒ}
const cat = new Animal();
const dog = new Animal();
cat.prototype; //undefined
dog.prototype; //undefined
cat.__proto__; // {constructor: ƒ}
dog.__proto__; // {constructor: ƒ}
이 상태를 그림으로 표현하면 아래와 같다.
콘솔창에서 [[Prototype]]이라고 찍히는 부분이 바로 __proto__이다.
이렇게 새롭게 만들어진 cat과 dog은 __proto__로 Animal의 프로토타입객체와 연결되어 있기 때문에,
다음의 문장이 말이 된다.
function Animal(){}
Animal.constructor // Function() { [native code] } 조상님 Function함수객체 찍힘
Animal.prototype; // {constructor: ƒ}
Animal.prototype.constructor // ƒ Animal(){}
const cat = new Animal();
const dog = new Animal();
cat.prototype; //undefined
dog.prototype; //undefined
cat.__proto__; // {constructor: ƒ}
dog.__proto__; // {constructor: ƒ}
cat.__proto__.constructor // ƒ Animal(){}
dog.__proto__.constructor // ƒ Animal(){}
//위를 한단계 줄여서 아래와 같이 적을 수도 있다.
cat.constructor // ƒ Animal(){}
dog.constructor // ƒ Animal(){}
이를 그림으로 나타내면 다음과 같다.
그리고 아래의 코드까지 표현한다면
Animal.constructor // Function()
이처럼 한 단계 더 타고 올라간다.
때문에 다음의 문장들이 모두 true가 된다.
Animal.prototype.constructor === Animal; // true
Animal.prototype === cat.__proto__; // true
prototype vs __proto__
prototype 프로퍼티 : 내가 원형일 때 존재함
- ="함수의 입장"에서 자식에게 물려줄 프로토타입 객체
- 함수 객체만 가지고 있다.
- 클래스는 .prototype으로 원형객체(prototype object)접근해야함
- 함수 객체가 생성자로 사용될 때, 이 함수를 통해 생성될 객체의 부모 역할을 하는 객체(prototype 객체)를 가르킨다.
- 즉, prototype 객체란 어떤 객체가 만들어지기 위해 그 객체의 모태가 되는 객체이고, 하위 객체들에게 물려줄 속성들이다.
[[Prototype]] 라고 뜨고 __proto__로 접근하는 프로퍼티 : 나의 원형을 가리킴
- ="객체의 입장"에서 자신의 부모 객체인 프로토타입 객체로 접근하는 링크
- 인스턴스에선 .__proto__로 부모 클래스에 접근해야함
- (함수 포함) 모든 객체가 가지고 있다.
- 부모인 prototype 객체를 가르키는 "링크link"라고 볼 수 있다.
관련글
'개념 > javaScript' 카테고리의 다른 글
[javaScript] 프로토타입 체인 (0) | 2022.07.25 |
---|---|
[javaScript] 정규 표현식 (0) | 2022.07.24 |
[javaScript] 객체지향프로그래밍 OOP (0) | 2022.07.22 |
[javaScript] 클래스와 인스턴스 (0) | 2022.07.22 |
[javaScript]내장 고차 함수 filter,map,reduce (0) | 2022.07.21 |