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원형 객체를 가리키므로 서로 같은 값을 가진다.
'Front-end > JavaScript' 카테고리의 다른 글
JS 프로토타입 5편 - OverRiding(커스텀 내장 메서드) (0) | 2023.01.23 |
---|---|
JS 프로토타입 4편 - prototype객체와 __proto__속성 (0) | 2023.01.23 |
JS 프로토타입 2편 - 상속 (0) | 2023.01.22 |
JS 프로토타입 1편 - 프로토타입 상속 (0) | 2023.01.21 |
JS 클로저 6편 - 클로저 사용 이유(메모리 절약 & 캡슐화)와 호이스팅 (1) | 2023.01.21 |