티스토리 뷰
6.1 프로토타입의 개념 이해
자바스크립트는 프로토타입 기반 객체지향언어이다. 클래스 기반 언어에서는 상속을 사용하지만, 프로토 타입 기반언어에서는 어떤 객체를 원형(prototype)으로 삼고 이를 으로써 상속과 비슷한 효과를 얻는다.
6.1.1 constructor, prototype, instance
var instance = new Constructor();
intance의 __proto__(dunder proto)라는 프로퍼티는 자동으로 Constructor.prototype을 참조한다. prototype 객체 내부에는 인스턴스가 사용할 메서드들이 저장되어있다.(length()같은 것들..) instace의 메서드를 사용하는 것은 constructor에 있는 메서드를 참조해서 사용하는 것이다.
__proto__는 직접 접근이 불가능 하고, Object.getPrototypeOf 또는 Reflect.getPrototypeOf를 통해서만 접근 가능하게 ECMA에서 정의를 했지만, 많은 브라우저들이 명세에 따르지 않으면서, ES6부터는 직접 접근이 가능하게 바뀌었다. 하지만, 코드의 일관성을 위해서 Object.getPrototypeOf() 또는 Object.create()를 사용하는게 좋다.
원래 인스턴스의 prototype은 instance.__proto__.~~로 접근하는게 맞지만, 브랜든 아이크(자바스크립트 창시자)가 생략이 가능하도록 고안하였다. 그래서 instance.~~ 로 바로 접근이 가능한 것이다.
"new 연산자로 Constructor를 호출해서 Object를 만들어서 instance에 대입연산을 하는데, 이 instance의 생략가능한 property인 __proto__는 Constructor의 prototype을 refer한다."
"__proto__는 생략이 가능한 프로퍼티이기 때문에, Constructer.prototype에 어떤 메서드나 프로퍼티가 있을 때, 인스턴스가 마치 자신의 것인 것 처럼사용이 가능한 것이다."

+ 개발자 도구콘솔에서 프로퍼티의 bold는 enumerable속성에 따라 표시된다. 열거 가능한 프로퍼티일 때 짙은색이다. 열거 가능한 프로퍼티는 for in으로 enumerate할 수 있다.
var arr = [1,2];
console.dir(arr);
console.dir(Array);
를 콘솔에서 찍어보자. static method는 참조받지 못하고 있음을 볼 수 있다. 그래서 Array.isArray등은 따로 쓰는 것이다.
6.1.2 constructor 프로퍼티
- 생성자 함수의 프로퍼티인 prototype객체 내부에는 constructor라는 프로퍼티가 있다. __proto__에도 들어간다. 이 프로퍼티는 단어 그대로 원래의 생성자 함수를 참조한다.
var arr1 = [1,2];
var arr2 = new arr.constructor(3,4);
* __proto__.constructor는 바꿀 수 있는 값이다. 그래서 원래의 생성자 함수를 알아내는데 참조 무결성을 제공해주지 않는다. 그런데 이 부분을 활용해서 class의 상속을 따라하는 것이다. 자바스크립트의 class는 일반적으로 생각하는 class와 많이 다르다.
6.2 프로토 타입 체인
6.2.1 메서드 오버라이드
- 인스턴스가 __proto__내부에 있는 프로퍼티와 동일한 이름의 프로퍼티를 가지고 있으면..?? 인스턴스의 프로퍼티를 따르게 된다. 원래의 __proto__에 들어있는 메서드를 쓰고 싶다면,
iu.__proto__.getName.call(iu);
이런 식을 쓰면 된다.
6.2.2 프로토타입 체인
- 배열 인스턴스의 __proto__를 까보면 그 안에 __proto__가 있는 것을 볼 수 있다. 그리고 그 내부 __proto__에는 Object의 __proto__가 들어있는 것을 볼 수 있다. Object가 최상위 prototype이기 때문이다. 자바의 최상위 클래스 Object와 같은 개념이다. 그게 바로 자바스크립트 상속의 비밀이다.
- constructor.constructor.constructor ... 이런식으로도 접근할 수도 있는데, 이런 경우는 브라우저에서 메모리에 가지고 있는거는 아니고 접근만 가능할 뿐이다. 콘솔에서 계속 까보면 나온다고 당황하지 말자.
6.2.3 객체전용 메서드는 어떤 방식으로 구현되어 있는가?
- 자바스크립트에서는 prototype에 새로운 메서드를 추가하는 방식등으로 최상위 객체인 Object조차 커스텀할 수 있다.
- 자바스크립트에서는 기본형 데이터들 조차 Object의 prototype을 참조한다. 그래서 Object 자료형을 위한 메서드들은 static(정적 메서드)으로 구현이 되어있다. Object.freeze(prameter)처럼 말이다. Object의 prototype에는 어떤 데이터이던지 활용가능한 메서드들이 들어있다. toString(), valueOf(), isPrototypeOf() 등...
-Object.create()는 __proto__가 없는 객체를 생성할때 사용하는 것이다. 그래서 Object.prototype에 접근 불가능하다.
그런데 왜쓰는가?하면 객체 자체의 무게가 가벼워지기 때문에 쓴다.
6.2.4 다중 프로토타입 체인
- 프로토타입 체인을 다중으로 연결하는 방법은 __proto__가 가리키는 대상인 생성자 함수를 prototype이 연결하고자 하는 상위 생성자 함수의 인스턴스를 바라보게 해주면 된다.

6.3 정리
- 어떤 생성자 함수를 new 연산자와 함께 호출하면 Constructor에서 정의된 내용을 바탕으로 새로운 인스턴스가 생성되는데 이 인스턴스의 __proto__ property는 생성자 함수의 prototype프로퍼티를 refer한다. 그런데 __proto__는 호출 시 생략이 가능해서 마치 인스턴스가 마치 자신의 것인거 마냥 호출이 가능하게끔 해준다.
- Constructor의 prototype에는 Constructor 프로퍼티가 또있다. 이게 중첩되면서 상속이 일어나는 것이다. __proto__를 중첩적으로 파고들면 Object.prototype을 만나게 된다. 대각선아래에서 부터 대각선위로 탐색해 나가며, 원하는 값을 찾으면 탐색을 중단한다.(프로토타입 체이닝)
- Object.prototype은 모든 데이터가 쓸 수 있기 때문에, Object만을 위한 프로퍼티는 static하게 구현되어있다.
- 프로토 타입 체이닝은 무한대의 단계로 이루어질 수 있다.
'FE > JavaScript 팔아요' 카테고리의 다른 글
[Note_deepDive]48장 자바스크립트의 모듈 시스템 (1) | 2022.09.22 |
---|---|
[Note_코어자바스크립트] 7장 클래스 [완] (0) | 2022.01.13 |
[Note_코어자바스크립트] 5장 클로저 (0) | 2022.01.04 |
[Note_코어자바스크립트] 4장 콜백 함수 (0) | 2021.12.28 |
[Note_코어자바스크립트] 3장 this (0) | 2021.12.21 |