ES6 에서 정의하는 메소드 형태로 정의한 함수는 그 내부에 [[HomeObject]]라는 내부슬롯을 가진다.
이 내부슬롯이 칭하는 대상은 자신을 바인딩하는 객체를 지칭한다.
이때, super 키워드는 자신을 바인딩하는 객체의 prototye에 접근하기 위한 식별자이다.
예를들어, super을 보게되는 가장 큰 예시는 상속을 하였을 때일텐데
class Base {
method1() {
return "hello";
}
}
class Derived extends Base {
constructor() {
super();
}
}
저때 constructor의 내부슬롯 [HomeObject]가 가리키는 대상은 자신을 감싸고 있는 객체라고 했다. 즉, 여기서 감싸고 있는객체란 Derived.prototye를 뜻한다. 왜냐하면,
평가당시를 기억해보자
class Derived가 평가되는 시점에서 생성되는 Derived.prototype 객체에는 constructor라는 프로퍼티가 존재하고 여기에 해당 constructor가 들어간다.
자 이제 그럼정리가 되었다
constructor에는 보이지않는 내부슬롯 [HomeObject]가 존재하고, 이것은 현재 Derived.prototype을 가리키고 있다.
그렇다면 super 키워드는 뭘까?
super키워드는 HomeObject가 내포하고 있는 내부슬롯 [[prototype]] 에 할당된 내용을 뜻한다.
즉, 여기에서 Derived.prototype의 [[prototype]]슬롯에 있는 존재는, 놀랍게도 처음 클래스들이 평가가 되는 순간에 extends 키워드로 인해 서로 연결되어 있던 Base의 prototype 객체다. 이 base의 prototype 객체에는 constructor가 존재하고, super을 호출하는 순간 자바스크립트 엔진은 자동으로 constructor의 유무를 확인하여 이 객체가 constructable 한지를 파악한 뒤, 가능하다면 생성자 함수로서 이용한다. 따라서, constructor을 실행시키는 것과 같다.
이것이 바로 super을 호출하면 인스턴스의 생성이 수퍼클래스에게 넘어간다고 하는 것이다.