[하루 30분 모던 자바스크립트 딥 다이브] 상속에 의한 클래스 확장

🤔클래스 상속과 생성자 함수 상속

  • 이 개념은 프로토타입 체인과는 다른 개념이다.
  • 기존 클래스를 상속받아 새로운 클래스를 확장하는 것!
  • 생성자 함수는 의사 클래스 상속 패턴을 사용하여 확장을 흉내 낼 순 있지만, 문법이 있지는 않다.
  • 클래스는 extends 키워드가 제공된다.
  • 클래스의 등장으로 의사 클래스 상속 패턴(모딥다 451p)은 더 이상 사용하지 않는다.

🤨extends 키워드

  • extends 키워드를 사용하여 상속받을 클래스를 정의할 수 있다
class super {}

class sub extends super{} //상속을 통한 확장
  • extends 키워드의 역할은 수퍼클래스와 서브클래스 간의 상속 관계를 설정하는 것이다
  • 클래스도 프로토타입을 통해 상속 관계를 구현한다.

🤔동적 상속?

  • extends 클래스는 클래스 뿐 아니라 생성자 함수를 받아서 클래스를 확장할 수 있다.
  • [[Construct]] 내부 객체를 갖는 함수 객체로 평가되는 모든 표현식이 가능하다. 이를 통해 동적으로 클래스 확장이 가능하다.
function super1 () {}
class super2 {}
let condition = true;

class sub extends (condeition ? super1 : super2) {}
// 조건에 따라 동적으로 확장이 가능하다

🤔서브클래스의 constructor

  • 서브 클래스에서 constructor 생략시 다음과 같은 constructor가 암묵적으로 실행된다.
class Super1 {}

class Sub extends super1 {}

// => constructor가 생략시 다음과 같은 constructor가 정의된다.
class sub extends super1 {
	constructor(...args) { super(...args); } 
}

🤔super 키워드

  • super 키워드는 함수처럼 호출 가능하고 this와 같이 식별자 처럼 참조가능하다.

super 호출

  • super를 호출하면 수퍼클래스의 constructor를 호출한다
class SuperClass {
	constructor (a,b) {
		this.a = a;
		this.b = b;
	}
}

class SubClass extends superClass {
	constructor(a,b,c){
		super(a,b); // super는 superClass의 constructor를 호출한다.
		this.c = c;
	}
}
  • super호출시 주의사항⭐
    1. 서브클래스의 constructor가 생략되지 않는다면 super는 반드시 호출되어야 한다!
    2. super를 호출하기 전까진 this를 참조할 수 없다!
    3. 반드시 서브클래스의 constructor에서만 호출한다!

super 참조

  • 수퍼클래스의 메서드 참조 가능.
  • suepr 참조가 동작하기 위해서 super가 참조하고 있는 메서드가 바인딩되어 있는 객체의 프로토타입을 찾을 수 있어야 한다. 이를 위해 메서드는 내부에 [[HomeObject]]를 가지며 자신을 바인딩 하고 있는 객체를 가리킨다.
  • 주의할 점은 ES6의 메서드 축약 표현으로 정의된 함수만이 [[HomeObject]] 내부슬롯을 가지며, 이를 갖는 함수만이 super 참조가 가능하다.

🤨상속 클래스의 인스턴스 생성 과정

  1. 서브클래스의 super 호출
    1. JS엔진은 클래스를 평가할 때 수퍼클래스와 서브클래스를 구분하기 위해 클래스 내부에 [[ConstructorKind]] 내부슬롯을 가진다. 상속받는 서브 클래스는 값이 “derived”로 설정되고, 아닌 클래스는 “base”가 설정된다.
    2. 서브 클래스는 자기 자신이 인스턴스를 생성하지 않고, 수퍼클래스에게 인스턴스 생성을 위임한다
  2. 수퍼클래스의 인스턴스 생성과 this바인딩
    1. 수퍼클래스에서 인스턴스 객체를 생성한다.
    2. new 연산자와 호출된 클래스는 서브클래스이다. 따라서 인스턴스는 new.target이 가리키는 서브클래스가 생성한 것으로 처리된다. (인스턴스는 서브 클래스의 프로토타입을 가리킨다)
  3. 수퍼클래스의 인스턴스 초기화
    1. 수퍼클래스의 constructor가 실행되며 this에 바인딩되어 있는 인스턴스를 초기화 한다.
  4. 서브 클래스 constructor로 복귀와 this바인딩
    1. 서브 클래스는 별도의 인스턴스를 생성하지 않고, 수퍼클래스에서 반환된 인스턴스 객체에 this 바인딩 된다.
    2. 때문에 super호출 이전까지 this호출이 불가능하다
  5. 서브 클래스의 인스턴스 초기화 & 반환