📌 프로토타입 상속
: 넓은 범위의 클래스를 좁은 범위의 클래스에 상속할 수 있다.
✔ extends
: 클래스를 다른 클래스의 자식으로 만들기 위해 class 선언, class 식에 사용됨 🔗
class ChildClass extends ParentClass { ... }
✔ super
: 부모 클래스의 생성자 함수를 호출하기 위해 사용됨 🔗
super([arguments]); // 부모 생성자 호출
super.functionOnParent([arguments]); // 부모 메서드만 따로 호출 가능
1. this 나오기 전에 사용 => Reference 에러
- 생성자 함수 내에선 한번만 사용 가능
- 정적 메서드(static) 도 호출 가능
class Human {
constructor() {}
static ping() {
return 'ping';
}
}
class Computer extends Human {
constructor() {}
static pingpong() {
return super.ping() + ' pong';
}
}
Computer.pingpong(); // 'ping pong'
4. super() 작성하지 않으면 생성자에 기본으로 super()가 생성됨 => 자식 클래스가 부모 클래스 속성, 메서드를 상속받음
5. super()로 부모 속성을 삭제할 시 reference 오류 생성
class Base {
constructor() {}
foo() {}
}
class Derived {
constructor() {}
delete() {
delete super.foo;
}
}
new Derived().delete(); // 참조오류: 'super'와 관련된 삭제가 유효하지 않습니다.
6. non-writable 속성 덮어쓸 수 없음
예를 들어 Object.defineProperty로 속성을 정의할 때, super의 속성 값을 덮어 쓸 수 없다.
class X {
constructor() {
Object.defineProperty(this, "prop", {
configurable: true,
writable: false,
value: 1
});
}
f() {
super.prop = 2;
}
}
var x = new X();
x.f();
console.log(x.prop); // 1
7. 객체 리터럴에서도 사용할 수 있음
Object.setPrototypeOf()로 obj2 prototype에 obj1을 세팅
var obj1 = {
method1() {
console.log("method 1");
}
}
var obj2 = {
method2() {
super.method1();
}
}
Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // logs "method 1"
상속 예시
Human 클래스
class Human {
constructor(name, age, gender){
this.name = nmae;
this.age = age;
this.gender = gender;
}
eat(){
console.log(`${name}가 밥을 먹었습니다.`)
}
sleep(){
console.log(`${name}가 잠을 잡니다.`)
}
}
Student는 Human의 부분집합이므로, 클래스를 상속하여 재사용할 수 있다.
class Student extends Human {
constructor(name, age, gender, grade){
super(name, age, gender) //super키워드로 부모 클래스의 생성자 함수 호출
this.grade = grade;
}
study(){
console.log(`${name}이 공부를 시작합니다.`)
}
}
extends와 super 키워드를 사용하여 Student 클래스가 Human의 메서드와 속성을 물려받게 한다.
추가로 다른 메서드와 속성을 넣을 수 있다.
✔ 오버라이딩
: 부모 클래스에서 이미 정의된 함수 등을 자식 클래스에서 같은 이름으로 사용하되, 내부 기능이나 속성을 바꾸어 사용
class Student extends Human {
constructor(name, age, gender, grade){
super(name, age, gender) //super키워드로 부모 클래스의 생성자 함수 호출
this.grade = grade;
}
study(){
console.log(`${name}이 공부를 시작합니다.`)
}
sleep(){
if(age === 19){
console.log(`고삼은 많이 잘 수 없었습니다.`)
}
else {
console.log(`${name}가 잠을 잡니다.`)
}
}
📌 DOM 프로토타입
DOM은 트리구조로 이루어져있으며 하나의 부모에 여러 개의 자식 요소가 달린 구조로 이루어져 있다.
=> 부모 클래스와 자식 클래스 존재
div의 __proto__는 HTMLDivElement 클래스이다.
계속 거슬러가다보면 EventTarget 클래스가 나오게 된다.
EventTarget의 윗 클래스는 이름이 나오지 않았고 그 위는 null이 나온 것으로 보아 이게 root라는 걸 알 수 있었다.
EventTarget.__proto__ 하면 바로 나올 줄 알았지만 이렇게 익명함수가 나왔다.
EventTarget.__proto__.__proto__를 하니 그제서야 Object가 나온다.
이유가 뭘까...?
위에서 거슬러 올라갔던 프로토타입과 같은지 확인했더니 맨 마지막 체인이 Object와 같음에 true를 반환했다.
그래서 확인해보니 constructor에 Object()라고 적혀있다.
✔ 궁금한 점
1. EventTarget.__proto__에 Object가 아니라 익명함수가 나오는 이유 =>
이유는 알 수 없었지만 실시간 세션 때 동기 분이 알려주신 힌트...!
아마 div로 들어가는 구조랑 EventTarget으로 바로 들어가는 구조가 달라서 그런 것 같다.
2. Window의 하위요소로 Document가 있다고 하는데, Document.__proto__는 Node이다.
부모는 하나만 가질 수 있는 게 아니었나...?
>> 콘솔창에 Window.document 해본 결과 undefined가 떴다.
여기서의 document는 다른 건가 싶다.
'Codestates SEB FE 42기 > 정리노트' 카테고리의 다른 글
S2 unit3 | 타이머 관련 API, 모듈 사용 방법, Fetch&Axios (0) | 2022.11.26 |
---|---|
S2 unit3 | (동기, 비동기) callback, Promise, async&await (0) | 2022.11.25 |
S2 unit2 | 프로토타입, 브라우저 속성 확인 루틴, 객체 속성과 요소 (0) | 2022.11.22 |
S2 unit2 | 객체 지향 프로그래밍 (Object Oriented Programming) (0) | 2022.11.20 |
S2 unit2 | [javascript] 클로저 모듈 패턴 / 클래스 생성 (0) | 2022.11.19 |