자바스크립트 회고록 - 4. super 참조

양희준·2022년 5월 16일
0

super 참조의 의문점

super([arguments]); // 부모 생성자 호출
super.functionOnParent([arguments]);

mdn에서는 이와 같이 정의를 하고 있다. super는 크게 함수로 호출되거나 super를 참조하여 사용하는데 super 참조는 상위 함수라고 하는 부분이 의문점이 생겼다.

super 참조와 프로토타입의 관계

super의 참조는 프로토타입 프로퍼티를 참조하여 사용할 수 있다.

class People {
  constructor(name, address) {
    this.name = name;
    this.address = address;
    this.age = 25;
  }
  // ES6 함수 표현으로 사용
  parentLog = () => {
    console.log(this.name, this.address, this.age);
  };
}

class Student extends People {
  constructor(name, address) {
    super(name, address);
  }
  childLog = () => {
    // super 참조를 사용한다.
    super.parentLog();
  };
}

const student = new Student("YHJ", "seoul");
/* 결과 :
TypeError: (intermediate value).parentLog is not a function
*/
student.childLog();

이와 같이 타입에러를 생성한다. 이유는 클래스에서 메소드 함수 표현을 사용하면 자동으로 프로토타입에 연결해주지만 화살표함수로 메소드를 생성하면 프로토타입에 연결해주지 않는다. 그러므로 super.parentLog는 undefined이므로 타입에러가 출력된다.

class People {
  constructor(name, address) {
    this.name = name;
    this.address = address;
    this.age = 25;
  }
  // 메소드 표현식
  parentLog() {
    console.log(this.name, this.address, this.age);
  }
}
// 프로토타입 프로퍼티 생성
People.prototype.phone = "01011112222";

class Student extends People {
  constructor(name, address) {
    super(name, address);
  }
  childLog = () => {
    // 출력 : YHJ seoul 25
    super.parentLog();
    // 출력 : 01011112222
    console.log(super.phone);
  };
}

const student = new Student("YHJ", "seoul");
student.childLog();

정상적으로 상속받은 메소드를 사용할 수 있게 된다. 이와 같이 super 참조는 결국 프로토타입을 참조하는 형태였던 것이다. 그래서 MDN에서는 메소드 표현식을 사용하여 메소드를 만들기 때문에 super 참조가 functionOnParent라고 설명하고 있는 것이다.

자바스크립트의 프로퍼티의 종류들

  • 정적 프로퍼티 : 객체에 키와 값으로 저장해 놓는 형태이다.
  • 인스턴스 프로퍼티 : 인스턴스를 생성할 떄 생성되며 각각의 인스턴스가 갖는 고유의 프로퍼티이다.
  • 프로토타입 프로퍼티 : 인스턴스를 생성할 때 상위 생성자로 부터 상속을 받아 사용한다.
class People {
  // 인스턴스를 생성하지 않아도 호출할 수 있다.
  static length = 10;
  constructor(name, address) {
    // 인스턴스 프로퍼티
    this.name = name;
    this.address = address;
    this.age = 25;
  }
  // 프로토타입 프로퍼티
  log() {
    console.log(this.name, this.address, this.age);
  }
}

// 인스턴스 2개 생성
const people1 = new People("YHJ", "seoul");
const people2 = new People("HGD", "busan");

// 정적 프로퍼티 호출
console.log(People.length);
// 인스턴스 프로퍼티 호출 (인스턴스 프로퍼티는 각각의 값을 갖는다.)
console.log(people1.address, people2.address);
// 프로토타입 메소드 호출 (이름과 주소 나이를 출력하는 함수의 본질은 바뀌지 않는다.)
people1.log();
people2.log();

참조 링크

ECMA-262 2020

14.6.13 Runtime Semantics: ClassDefinitionEvaluation With parameters classBinding and className.

  • super를 호출하면 부모의 constructor 먼저 불러온 뒤 자식의 constructor을 불러오기 때문에 프로퍼티의 이름을 똑같이 하면 값이 갱신된다.
  • super의 참조는 prototype 프로퍼티나 메소드를 참조하는 것이다. 클래스의 메소드는 자동으로 프로토타입으로 연결되기 때문에 참조가 가능하다.
  • constructor의 요소들이 super 참조가 안되는 이유는 인스턴트 프로퍼티이기 때문이다.
profile
JS 코린이

0개의 댓글