모던 JavaScript 튜토리얼 파트 1 :: 8장 - "프로토타입과 프로토타입 상속", 9장 - "클래스" 정적 메서드까지 정리
글 작성자: Coding Groot
정리
시간이 없어서 텍스트로 내용을 정리하지는 못했습니다.
스터디 때 코어 자바스크립트 내용을 참고해서 쓴 자료를 올립니다.
excalidraw에서 진행했습니다.
https://excalidraw.com/#json=UPKDLXv3hxLCB5lt9MDKv,2NQftxJsB_qiK6Z2CnP3pw
1. 프로토타입 상속
2. 함수의 prototype 프로퍼티
3. 내장 객체의 프로토타입
4. 프로토타입 메서드와 __proto__가 없는 객체
프로퍼티를 이용해서 상속을 해보자
// 부모
function Parent(prop1) {
this.prop1 = prop1 || 'empty prop1';
}
// 부모의 프로토타입 객체 생성
Parent.prototype.getProps = function () {
return {
prop1: this.prop1,
};
};
// 자식
function Child(prop1, prop2) {
this.prop1 = prop1;
this.prop2 = prop2;
}
// 프로토타입을 이용한 상속
// 1. 부모 클래스를 Prototype으로 지정
Child.prototype = new Parent();
// 2. 다시 자식 클래스의 생성자를 복원
Child.prototype.consturctor = Child;
// Child Instance 생성
const childInstance = new Child('Hello', 'World');
// 메서드 호출
console.log(childInstance.getProps());
console.dir(childInstance);
프로토타입 체인을 이용하면 상속을 다음과 같이 구현할 수 있습니다.
하지만 출력 결과를 보면 다음과 같은 문제점이 있습니다.
자식에서 prop1이 지워진 경우 이상한 동작을 할 수 있습니다.
undefined가 반환되지 않고 "empty prop1"이라는 문자열이 반환됩니다.
부모가 가지고 있는 변수들을 숨기고 싶습니다.
메서드들만 존재하는 조금 더 추상적인 클래스를 만들 수 없을까요?
이것은 비어있는 객체를 중간에 둬서 해결할 수 있습니다.
Bridge 객체
빈 객체(Bridge 객체)를 이용해서 방금 사용한 프로토타입의 문제를 해결해봅시다.
// 부모
function Parent(prop1) {
this.prop1 = prop1 || 'empty prop1';
}
// 부모의 프로토타입 객체 생성
Parent.prototype.getProps = function () {
return {
prop1: this.prop1,
};
};
// 자식
function Child(prop1, prop2) {
this.prop1 = prop1;
this.prop2 = prop2;
}
/**
* 아무런 프로퍼티도 없는 비어있는 생성자
*/
function Bridge() {}
// 1. Brige의 프로토타입 = Parent의 프로토타입
Bridge.prototype = Parent.prototype;
// 2. Child의 프로토타입 = 브릿지 인스턴스
Child.prototype = new Bridge();
// 3. Child의 생성자를 복원해준다
Child.prototype.consturctor = Child;
// 브릿지 인스턴스 덕분에 Parent의 prop1은 노출되지 않는다
const childInstance = new Child('Hello', 'World');
// 메서드 호출
console.log(childInstance.getProps());
console.dir(childInstance);
더글라스 크락포드의 Bridge
이 방법은 더글라스 크락포드(json 만드신 분이닷..)가 추천하는 방법입니다.
Closure를 이용해서 bridge 객체도 캡슐화해서 재활용할 수 있습니다.
/**
* Closure를 이용해서 브릿지 생성자 함수를 만들어보자.
* 이 함수는 Super, Sub를 넘기면 자동으로 상속 구조를 만들어준다.
* 이 함수는 단 한번만 생성하고 계속 재활용할 수 있다.
*/
function createExtendsFunction() {
// 비어있는 브릿지 객체를 만든다.
// 캡슐화된 bridge 객체를 상속 관계를 만들 때마다 생기지 않고 재활용한다. (참고: Closure)
function bridge() {}
return function (superClass, subClass) {
// 1. 기존 브릿지 객체의 프로토타입을 부모 프로타입으로 지정한다.
bridge.prototype = superClass.prototype;
// 2. 자식 클래스의 프로토타입으로 브릿지를 만든다.
subClass.prototype = new bridge();
// 3. 자식 클래스의 생성자를 복원한다.
subClass.prototype.constructor = subClass;
// 4. 부모 생성자를 활용할 수 있도록 SuperClass 메서드를 만든다.
subClass.prototype.SuperClass = superClass;
};
}
// extendsFunction 함수를 만든다.
// 한번만 호출하고 extendsFunction을 통해 하나의 브릿지 객체를 재활용한다.
const extendsFunction = createExtendsFunction();
/* ------------------------------------------------------- */
// 부모
function Parent(prop1) {
this.prop1 = prop1 || 'empty prop1';
}
// 부모의 프로토타입 객체 생성
Parent.prototype.getProps = function () {
return {
prop1: this.prop1,
};
};
// 자식
function Child(prop1, prop2) {
// 직접 부모 인스턴스를 초기화하지 않고 미리 달아놓은 SuperClass 프로퍼티를 이용해서 초기화하자
this.SuperClass(prop1); // == this.prop1 = prop1; <- 여기서 this는 생성자의 this이므로 클래스 인스턴스가 된다.
this.prop2 = prop2;
}
// 상속 관계를 만든다.
extendsFunction(Parent, Child);
// 브릿지 인스턴스 덕분에 Parent의 prop1은 노출되지 않는다
const childInstance = new Child('Hello', 'World');
// 메서드 호출
console.log(childInstance.getProps());
console.dir(childInstance);
이렇게 Bridge 객체로 부모 프로토타입의 프로퍼티를 숨기는 것은 ES2015 시절까지 흔하게 쓰였다고 합니다.
하지만 Object.create도 있고 Class 문법이 생기고부터는 extends를 통해 쉽게 구현할 수 있습니다.
궁금하다면 다음 블로그를 참고해보세욧ㅎㅎ
[velog] JS에서 상속을 구현하는 방법 3가지 - ansrjsdn
출처
- 모든 이미지는 코어 자바스크립트 책을 참고해서 만들었습니다.
- 이미지는 https://excalidraw.com/를 사용해서 만들었습니다.
- 브릿지 객체 부분 참고: [velog] JS에서 상속을 구현하는 방법 3가지 - ansrjsdn
- https://ko.javascript.info/
원본 스터디 이미지: https://drive.google.com/file/d/1kcZMF3ibTQcMOHN7YoqHBXIC57LaNE-S/view?usp=share_link
반응형
댓글
이 글 공유하기
다른 글
-
[JS] Lexical Environment로 알아보는 Closure
[JS] Lexical Environment로 알아보는 Closure
2023.01.16 -
모던 JavaScript 튜토리얼 파트 1 :: 6장 "함수 심화학습" 정리
모던 JavaScript 튜토리얼 파트 1 :: 6장 "함수 심화학습" 정리
2023.01.16 -
모던 JavaScript 튜토리얼 파트 1 :: 5장 "자료구조와 자료형" 정리
모던 JavaScript 튜토리얼 파트 1 :: 5장 "자료구조와 자료형" 정리
2023.01.09 -
모던 JavaScript 튜토리얼 파트 1 :: 3장 "코드 품질", 4장 "객체:기본" 정리
모던 JavaScript 튜토리얼 파트 1 :: 3장 "코드 품질", 4장 "객체:기본" 정리
2023.01.02