코어 자바스크립트를 읽으면서 공부한 내용을 저의 입맛에 맞춰 정리하였습니다.
혹시 이 글을 읽게 되시면 잘못된 내용이 있을 수 있으니 비판적인 시각으로 읽으시는 걸 추천드립니다.
프로토타입
자바스크립트는 프로토타입 기반 언어입니다. 클래스 기반 언어에서는 '상속'을 사용하지만 프로토타입 기반 언어에서는 어떤 객체를 원형으로 삼고 이를 복제(참조)함으로써 상속과 비슷한 효과를 얻습니다.
1. 프로토타입 개념 이해
- 어떤 생성자 함수를 new 연산자와 함께 호출하면
- Constructor에서 정의된 내용을 바탕으로 새로운 인스턴스가 생성됩니다
- 이때 instance에는 proto라는 프로퍼티가 자동으로 부여되는데
- 이 프로퍼티는 Constructor의 prototype이라는 프로퍼티를 참조합니다.
prototype이라는 프로퍼티와 proto의 관계가 프로토타입 개념의 핵심입니다. 이 둘 모두 객체인데 prototype 객체 내부에는 인스턴스가 사용할 메서드를 저장합니다. 그러면 인스턴스에서도 숨겨진 프로퍼티인 proto를 통해 이 메서드들에 접근할 수 있게 됩니다.
proto는 생략가능한 프로퍼티입니다. 그렇기 때문에 생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 됩니다.
suzi.__proto__.getName
-> suzi(.__proto__).getName
-> suzi.getName
var arr = [1, 2]
console.dir(arr)
console.dir(Array)
위의 코드를 실행했을 때, arr은 proto를 통해 push, pop과 같은 배열 메서드를 사용할 수 있습니다. array를 확인해 보면 함수의 정적 메서드인 from, isArray 등이 보이고 prototype에는 proto와 동일한 메서드 들이 들어있습니다.
2. constructor 프로퍼티
생성자 함수의 프로퍼팅인 prototype객체 내부에는 constructor객체도 들어있습니다. 이 프로퍼티는 원래의 생성자 함수를 참조합니다. 이는 인스턴스로부터 그 원형이 무엇인지 알 수 있는 수단이 됩니다.
var arr = [1, 2];
Array.prototype.constructor === Array; // true
arr.__proto__.constructor === Array; // true
arr.constructor === Array; // true
var arr2 = new arr.constructor(3, 4);
console.log(arr2); // [3, 4]
한편 읽기 전용 속성이 부여된 예외적인 경우를 제외하고는 값을 바꿀 수 있습니다. 하지만 constructor를 변경하더라도 참조하는 대상이 변경될 뿐 이미 만들어진 인스턴스의 원형이 바뀐다거나 데이터 타입이 변하는 것은 아님을 알 수 있습니다.
3. 프로토타입 체인
1. 메서드 오버라이드
메서드 오버라이드는 메서드 위에 메서드를 덮어 씌웠다는 표현입니다.
자바스크립트 엔진이 메서드를 찾는 방식은 가장 가까운 대상인 자신의 프로퍼티를 검색하고, 없으면 그다음으로 가까운 대상인 ㅔ개새를 검색하는 순서로 진행 됩니다.
2. 프로토타입 체인
proto 프로퍼티 내부에 다시 proto프로퍼티가 연쇄적으로 이어진 것은 프로토타입 체인이라고 하고, 이 체인을 따라가며 검색하는 것을 프로토타입 체이닝이라고 합니다.
3. 객체 전용 메서드의 예외사항
어떤 생성자 함수이든 prototype은 반드시 객체이기 때문에 Object.prototype이 언제나 프로토타입 체인의 최상단에 존재하게 됩니다. 따라서 객체에서만 사용할 메서드는 다른 여느 데이터 타입처럼 프로토타입 객체 안에 정의할 수 없습니다.
그렇기에 객체 전용 메서드들은 부득이 Object.portotype이 아닌 Object에 스태틱메서드로 부여할 수밖에 없습니다.
4. 정리
어떤 생성자 함수를 new 연산자와 함께 호출하면 Consrtuctor에서 정의된 내용을 바탕으로 새로운 인스턴스가 생성되는데, 이 인스턴스에는 proto라는, Constructor의 prototype프로퍼티를 참조하는 프로퍼티가 자동으로 부여됩니다. proto는 생략 가능한 속성이라서 마치 자신의 메서드인 것처럼 호출할 수 있습니다
'CS' 카테고리의 다른 글
[JS] Proxy 객체 (0) | 2023.07.06 |
---|---|
[JS] 클로저 (feat : 코어 자바스크립트) (0) | 2022.12.21 |
[JS] 콜백함수 (feat : 코어 자바스크립트) (0) | 2022.12.16 |
[JS] this (feat : 코어 자바스크립트) (0) | 2022.12.15 |
[JS] 실행컨텍스트 (feat : 코어 자바스크립트) (0) | 2022.12.14 |