01. 상속
상속이란 일반적으로 특정 객체가 다른 객체로부터 기능을이어받는 것을 말합니다.
자바스크립트에서는 클래스가 아닌 객체를 상속합니다. 자바스크립트의 상속은 프로토타입 체인이라고 부르는 객체의 자료 구조로 구현되어 있으며, 프로토타입 상속이라고 부릅니다.
(자바스크립트는 프로토타입 상속에 기반을 둔 객체 지향 언어입니다.)
상속을하는이유
상속을 사용하면 이미 정의된 프로퍼티와 메서드의 코드를 재사용할 수 잇고 새로운 기능을 추가해서 확장된 객첼르 만들 수도 있습니다. 중복 코드를 작성하지 않아도 되므로 유지 보수성이 높은 프로그램을 만들 수 있습니다.
내부 프로퍼티
모든. 객체는 내부 프로퍼티를 가지고 있습니다. ECNAScript6 부터는 __proto__ 프로퍼티를 지원합니다.
프로토타입 체인
객체의 __proto__ 프로퍼티는 그 객체에게 상속을 해 준 부모 객체를가리킵니다. 따라서 객체는 __proto__ 프로퍼티가 가리키는 부모 객체의 프로퍼티를 사용할 수 있습니다.
프로토타입 체인 실행 과정
▶ objC.sayHello()가 호출되면 먼저 objC 자신이 sayHello라는 프로퍼티를 소유하고 있는지 확인합니다. 하지만 objC 안에서는 찾을 수 없습니다.
▶ 다음으로 objC.__proto__ 가 가리키는 objB가 sayHello라는 프로퍼티를 소유하고 있는지 확인합니다. 역시 objB안에서도 찾을 수 없습니다.
▶ 이제 objB.__proto__ 가 가리키는 objA가 sayHello 라는 프로퍼티를 소유하고 있는지 확인합니다.
▶ sayHello 프로퍼티를 찾았습니다. 이제 objA.__proto__ 를 사용합니다.
이번에는 objA.sayHello 코드 안에서 this.name을 검색해 봅니다.
▶ 먼저 objC스스로가 name 이라는 프로퍼티를 소유하고 있는지 확인합니다 하지만 objC 안에서는 찾을 수 없습니다.
▶ 다음으로 objC.__proto__ 가 가리키는 objB 가 name 이라는프로퍼티를 소유하고 있는지 확인합니다.
▶ name 프로퍼티를 찾았습니다. 이 값을 this.name 값으로 사용합니다.
이처럼 자신이 갖고 있지 않은 프로퍼티를 __proto__ 프로퍼티가 가리키는 객체를 차례대로 거슬러 올라가며 검색합니다. 이와 같은 객체의 연결 고리를프로토타입 체인이라고 합니다.
객체는 자신이 가지고 있지 않은 특성(프로퍼티와 메서드)을 프로토타입 객체에 위임(delegate)한다고 할 수 있습니다. (위임 해준다는 말)
이처럼 자바스크립트는 프로토타입 체인을 사용하여 객체의 프로퍼티를 다른 객체로 전파합니다. 이를 프로토타입 상속이라고 합니다. 프로토타입상속을하는객체지향 언어를 가리켜 프로토타입 기반 객체 지향 언어라고 합니다.
** 실제로 프로그래밍을 할 때는 __proto__ 프로퍼티 값을 직접 입력해서 상속하지는 않습니다.
02. new 연산자의 역할
생성자를 new 연산자로 호출하면 객체의 생성, 프로토타입의 설정, 객체의 초기화를 수행합니다.
03. 프로토타입 객체의 프로퍼티
프로토타입 객체는 기본적으로 constructor 프로퍼티와 내부 프로퍼티[[Prototype]](__proto__)을 가지고 있습니다.
constructor 프로퍼티
constructor 프로퍼티는 함수 객체의 참조를 값으로 갖고 있습니다.
function F(){}
console.log(F.prototype.constructor); //Function F() {}
생성자의 prototype 프로퍼티가 프로토타입 객체를 가리키며, 이 프로토타입 객체의 constructor 프로퍼티가 생성자를 가리키는 연결 고리' 로 묶여 있습니다. 반면 생성자로 생성한 인스턴스는 생성될 때의 프로토타입 객체의 참조만 가지고 있을뿐 생성자와는 직접적인 연결 고리가 없습니다.
내부 프로퍼티 [[Prototype]]
프로토타입 객체의 프로토타입은 Object.prototype 입니다. 이 덕분에 생성자로 생성한 인스턴스가 Object.prototype의 프로퍼티를 사용할 수 있습니다. 또한 Object.prototype의 프로토타입은 null을 가리킵니다.
function F(){};
console.log(F.prototype.__proto__); // -> Object{}: Object.prototype
프로토타입 객체의 교체 및 constructor 프로퍼티
생성자가 가진 prototype 프로퍼티 값을 새로운 객체로 교체할 때는 주의해야 합니다. 프로퍼티만 정의되어 있는 새로운 객체를 prototype 프로퍼티 값으로 대입하면 인스턴스와 생성자 사이의 연결 고리가 끊겨 버립니다. 그 객체에는 constructor 프로퍼티가 없기 때문입니다.
인스턴스 생성 후에 생성자의 프로토타입을 수정하거나 교체한 경우
인스턴스를 생성한 후에 생성자의 prototype 프로퍼티 값을 다른 객체로 교체해도 인스턴스의 프로토타입은 바뀌지 않습니다. 다시말해 인스턴스의 프로퍼티는 생성되는 시점의 프로토타입에서 상속 받습니다. 생성된 후에는 생성자의 프로토타입을 바꾸어도 교체한 객체로부터는 프로퍼티를 상속받지 않습니다.
두번세번 읽어봐도 완전히 이해가 되지는 않는다.
어렵지만 천천히 더 찾아보면서 이해해보자..
참고문헌
📌 모던 자바스크립트 입문 책
'FRONTEND > JS' 카테고리의 다른 글
[JS] 프로토타입 (0) | 2022.05.02 |
---|---|
[개발의 본질] 투두리스트 JS로 만들기 | 토이 프로젝트 02 (0) | 2022.04.03 |
[JS] 객체 생성과 프로토타입 (0) | 2022.03.24 |
[JS] appendChild 를 이용해서 노드를 옮기는 방법 (1) | 2022.03.16 |
[JS] 노드 생성과 삽입 createElement & appendChild (0) | 2022.03.14 |