JavaScript 문법 - prototype chaining

💻 prototype chaining에 대해 알아보자


📌 먼저 아래의 그림을 이해하자

배열 리터럴은 Array 생성자 함수와 Array.prototype로 이루어져 있다.

Array.prototype에는 배열메서드가 모두 담겨있다.
즉, Array.prototype객체이다.

그리고 __proto__가 생략 가능하기 때문에 배열 instance가 마치 자신의 메서드인것처럼 호출할 수 있게 된다.

그런데, prototype가 객체라는 말은
곧, Object 생성자 함수의 new 연산자로 생성된 instance라는 말이 된다.
따라서 Object의 prototype를 상속받게 된다.

이제 배열은 Object의 prototype에 있는 메서드 역시 마치 자신의 것처럼 사용할 수 있게 되었다.

이처럼 __proto__라는 빨간색 선을 따라서 연결된 것을 prototype chaining이라고 부른다.

prototype는 모두 객체이므로 모든 데이터 타입은 한결같이 이와 동일한 구조를 따른다.


👀 문자열을 예로 들어 살펴보자

문자열의 경우 메서드를 사용하려고 할 때, 자동으로 String의 instance로 변환된다.

기타 데이터 타입도 모두 이와 같은 생성자 함수가 존재하고, 각 생성자 함수의 prototype에는 각 데이터 타입에만 해당하는 메서드들이 정의되어 있다.

그리고 모든 데이터 타입에 대해서 생성자 함수의 prototype__proto__로 연결된 Object.prototype에는
자바스크립트 전체를 통괄하는 공통된 메서드들이 정의 되어 있다.

Object.prototype에 정의된 메서드들은 모든 데이터 타입이 prototype chaining을 통해 접근할 수 있다


😠 그러나 이러한 경우 객체의 prototype에는 해당 객체에만 적용될 메서드를 정의해둘 수 없다.
객체의 prototype에 있는 메서드들은 모든 데이터타입에 적용되기 때문이다.

다른 데이터 타입들처럼 객체 리터럴에 메서드를 호출하고 싶은데, 그러자니 다른 데이터 타입이 같은 메서드를 상속받아 버리게 된다.
그래서 어쩔 수 없이 객체 생성자 함수에 직접 메서드 함수를 정의해버렸다 .

예를 들어 배열의 경우 instance 배열을 통해 Array property(ex, length)에 접근이 가능한데(prototype의 property로 메서드를 정의했기 때문), 반면에 Object의 경우 instance를 통해 메서드에 접근하지 못하고 Object.assign()과 같이 Object 생성자 함수를 사용해 메서드에 접근해야 한다.


📟 예제를 통해 살펴보자(배열인 경우)

1. arr.toString을 정의한 결과 값 출력
   
   
2. Array.toString 결과 값 출력(call을 통해 arr로 this 바인딩)


3. Object.toString 결과 값 출력
		

1. Array.toString 결과 값 출력(prototype로 직접 메서드 정의)

2. Array.toString 결과 값 출력(call을 통해 arr로 this 바인딩)

3. Object.toString 결과 값 출력

아래 사진, console.dir(Object) toString 메서드 존재


📚 예제를 통해 살펴보자(객체인 경우)

obj.toString()을 할 경우, Object.toString이 호출된다.

그렇기에 문자열로 이쁘게 출력하기 위해서 아래와 같이 코드를 구현해봤다.

😠 하지만 b : [object Object]가 출력되어 여전히 맘에 들지 않는다.

이렇게 출력되는 이유는 b가 객체이므로 key가 b일때, this가 object를 가리키기 때문이다.

좋은 웹페이지 즐겨찾기