본문 바로가기

Today I Learned

모던 자바스크립트 Deep Dive 25장 클래스

클래스 = 프로토타입의 문법적 설탕?

프로토타입 기반 객체지향 언어는 클래스가 필요없는 객체지향 프로그래밍 언어다. ES6 도입된 클래스는 객체지향 프로그래밍에 익숙한 프로그래머가 더욱 빠르게 학습할 있도록 도입된 새로운 매커니즘이다. 클래스는 생성자 함수보다 엄격하고 생성자 함수가 제공하지 않는 기능도 제공한다.

클래스의 특징

  1. 클래스를 new 연산자없이 호출하면 에러가 난다.
  2. extends, super 키워드를 제공한다.
  3. 호이스팅이 발생하지 않는 것처럼 동작한다.
  4. 클래스 내의 코드는 암묵적으로 strict mode 적용된다.
  5. [[Enumerable]] 프로퍼티 어트리뷰트 값이 false.

클래스 정의

이름은 파스칼 케이스를 사용한다. 표현식을 사용해도 된다. 값처럼 사용할 있는 일급 객체다.

클래스 호이스팅

프로토타입과 생성자 함수는 언제나 쌍으로 존재한다.(19.5 참고) 클래스는 클래스 정의 이전에 참조할 없다. 클래스 선언문 이전에 일시적 사각지대에 빠지기 때문에, 호이스팅이 발생하지 않는 것처럼 동작한다.

메서드

클래스는 인스턴스를 생성하기 위한 생성자 함수다. constructor 생략하면 암묵적으로 정의된다. constructor 안에서 인스턴스 생성과 초기화를 담당하고 있기 때문에, 인스턴스를 초기화할때는 contructor 생략해서는 안된다.

정적 메서드와 프로토타입 메서드의 차이

  1. 둘은 자신이 속해있는 프로토타입 체인이 다르다.
  2. 정적 메서드는 클래스로 호출하고 인스턴스 프로퍼티를 참조할 없다.
  3. 프로토타입 메서드는 인스턴스로 호출하고 인스턴스 프로퍼티를 참조할 있다.

this 사용하지 않는 메서드는 정적 메서드로 정의하는 것이 좋다.

프로퍼티

인스턴스 프로퍼티는 언제나 public하다. 자바스크립트는 private 키워드와 같은 접근 제한자를 지원하지 않는다. 대신 # 이용해서 private 필드를 정의할 있다. , prevate 필드는 반드시 클래스 몸체에 정의해야 한다.

class Person{
	// private 필드 정의
	#name = '';
	
	constructor(name){
		this.#name = name;
	}
}

상속

  • 상속을 통해 확장된 클래스 : 서브 클래스 = 파생 클래스 = 자식 클래스
  • 상속된 클래스 : 수퍼 클래스 = 베이스 클래스 = 부모 클래스

extends 키워드는 클래스뿐만 아니라 생성자 함수도 상속받을 있다. [[Construct]] 내부 메서드를 갖는 함수 객체로 평가될 있는 모든 표현식을 사용할 있다. 동적으로 정할 수도 있다.

class Derived from (condition ? Base1 : Base2) {}

super 키워드 사용 주의사항

  1. 서브클래스애서 constructor 사용한다면 반드시 super 호출해야한다.
  2. constructor에서 super 호출하기 전에는 this 참조할 없다.
  3. super 키워드는 서브클래스의 constructor에서만 호출한다.

메서드 내에서 super 참조하면 수퍼클래스의 메서드를 호출할 있다. 메서드 축약 표현으로 정의해야만 한다.

서브클래스는 자신이 직접 인스턴스를 생성하지 않고, 수퍼클래스에 인스턴스 생성을 위임한다. 그렇기 때문에 서브클래스의 constructor에서 반드시 super 호출해야하는 이유다. 그렇지 않으면 에러가 발생한다. 서브클래스의 constructor에서 super 호출하기 전에는 this 참조할 없다.