Front-end/JavaScript

JS 프로토타입 3편 - prototype chain

파리외 개발자 2023. 1. 23. 18:07

Prototype Chain

JS는 프로토타입 기반 언어로 

prototype 연결고리가 존재해서 상속을 받을 수 있다.

hasOwnProperty

const obj = { name: "obj" };

obj.hasOwnProperty("name"); //true

해당 메서드는 Object내장 메서드로 상속받아서 사용하는 속성이 아닌

자신만의 속성인지 아닌지 확인하는 기능을 가진다.

obj에 name속성을 정의해 줬으므로 값은 true를 가진다.

//function
function multyplyBy5(num) {
  return num * 5;
}

multyplyBy5.hasOwnProperty("call"); //false

함수 또한 객체의 한 종류이므로 해당 메서드를 사용할 수 있고

정의한 함수에 call속성은 없다고 나온다.

그런데 모든 함수는 내장메서드인 call, bind 등을 가지는 데 

왜 정의된 함수의 속성에는 없다고 나오는 것일까?

이는 정의한 함수는 함수이되, Function 객체를 상속받아 

Function의 내장 메서드들을 사용하는 것이기 때문이다.

__proto__ & prototype

//Function의 프로토타입 객체가 제공하는 내장메서드
multyplyBy5.__proto__; //Function.prototype
Function.prototype; //multiplyBy5.__proto__

정의한 함수인 multyplyBy5의 숨겨진 속성 __proto__와

함수의 원형객체인 Function의 prototype속성의 결괏값은 같다.

정의된 함수의 __proto__와 Function의 prototype이 같다고 나오는 이유는

multyplyBy5가 Function을 상속받고 있음을 의미한다.

우리가 정의하는 모든 함수들은 Function을 자동으로 상속받는다.

자동으로 __proto__속성이 생겨나고 이 속성은 

함수원형인 Function의 prototype속성을 자동적으로 가리키고 있다.

그렇기 때문에 함수를 정의하고 우리가 정의하지 않은 함수의 내장메서드를 사용하려 할 때

우리의 함수는 Function을 상속받고 거기에 존재하는 함수 내장메서드들을

상속해서 가져다 사용할 수 있는 것이다.

여기서 끝이 아니다.

Function객체는 Object를 같은 방식으로 상속받고 있다.

제일 처음에 사용했던 hasOwnProperty는 Object에서 상속받아 사용한 메서드다.

함수원형의 prototype객체의 __proto__속성은 마찬가지로 

객체원형의 prototype객체를 가리키며 둘은 같다.

Object.prototype.__proto__; //null
Function.prototype.__proto__.__proto__; //null

또한 객체원형인 Object도 마찬가지로 프로토타입체인이 존재하는데

여기서는 null을 가리키며 체인이 끊겼음을 의미한다.

이는 함수원형인 Function의 두 단계 위 상속, __proto__.__proto__또한 null을 가리키는 것을 

마찬가지로 의미한다.

array's prototype chain

//array
const array = [];
array.hasOwnProperty("map"); //false 상속받음
array.__proto__.hasOwnProperty("map"); //true

함수대신 배열로 같은 프로토타입 체인을 확인해 본다.

빈 배열인 array는 map함수를 사용할 수 있지만 상속받은 메서드이기 때문에

hasOwnProperty값은 false가 나온다.

하지만 __proto__를 통해 한 단계 올라간, (여기선 배열의 원형객체인 Array)에서

hasOwnProperty를 사용하면 true값이 나오는 것으로 봐서

array는 Array객체의 메서드인 map을 가져다 쓴다는 것을 알 수 있다.

배열도 함수와 마찬가지로 배열원형객체를 상속받으며

배열 내장 메서드들을 여기서 가져다 쓰는 것을 알 수 있다.

마지막으로 함수와 배열 둘 다 두 번 상속을 타고 올라간다면

Object원형 객체를 가리키므로 서로 같은 값을 가진다.