클래스는 기존 프로토타입 기반 패턴을 클래스 기반 패턴처럼 사용할 수 있도록 하는 문법적 설탕이다라고 하기보다는 새로운 객체 생성 메커니즘이다라고 하는 것이 더 적절하다.
프로토타입 기반 객체지향 언어는 클래스가 필요 없는 객체지향 프로그래밍 언어로 ES5에서 클래스 없이도 생성자 함수와 프로토타입을 통해 객체지향 언어의 상속을 구현할 수 있다.
ES6에서 도입된 클래스는 클래스 기반 객체지향 프로그래밍에 익숙한 프로그래머들을 위해 클래스 기반 객체지향 프로그래밍 언어와 매우 흡사한 새로운 객체 생성 메커니즘을 제공한다.
클래스와 생성자 함수의 정의 방식은 형태적인 면에서 매우 유사하다.
class Person {
/* 생성자 함수 */
constructor(name) {
this.name = name;
}
/* 프로토타입 메서드 */
sayHi() {
console.log(`Hi! My name is ${this.name}`);
}
/* 정적 메서드 */
static sayHello() {
console.log('Hello!');
}
}
var Person = (function () {
/* 생성자 함수 */
function Person(name) {
this.name = name;
}
/* 프로토타입 메서드 */
Person.prototype.sayHi = function () {
console.log('Hi! My name is' + this.name);
};
/* 정적 메서드 */
Person.sayHello = function () {
console.log('Hello!');
};
/* 생성자 함수 반환 */
return Person;
}());
클래스는 생성자 함수와 매우 유사하게 동작하지만 아래와 같이 몇 가지 차이가 있다.
클래스는 class 키워드를 사용하여 정의하며, 일반적으로 클래스 이름은 파스칼 케이스를 사용한다.
클래스는 함수이기 때문에 값처럼 사용할 수 있는 일급 객체이다.
클래스는 일급 객체로서 아래와 같은 특징을 가진다.
클래스 몸체에서 정의할 수 있는 메서드는 constructor(생성자), 프로토타입 메서드, 정적 메서드이다.
ECMAScript® 2023 Language Specification
Classes [ES6] * JavaScript for impatient programmers (ES2022 edition)
클래스 선언문으로 정의한 클래스는 런타임 이전에 먼저 평가되어 함수 객체를 생성한다.
클래스가 평가되어 생성된 함수 객체는 생성자 함수로서 호출할 수 있는 함수, 즉 constructor이다.
프로토타입과 생성자 함수는 언제나 쌍으로 존재하기 때문에 프로토타입도 더불어 생성된다.
클래스 선언문도 변수 선언, 함수 정의와 마찬가지로 호이스팅이 발생하지만, let, const 키워드로 선언한 변수처럼 일시적 사각지대(TDZ)에 빠지기 때문에 호이스팅이 발생하지 않는 것처럼 동작한다.
클래스는 생성자 함수이며 new 연산자와 함께 호출되어 인스턴스를 생성한다.
클래스는 인스턴스를 생성하는 것이 유일한 존재 이유이므로 반드시 new 연산자와 함께 호출해야 한다.
클래스 표현식으로 정의된 클래스의 경우 클래스를 가리키는 식별자를 사용해 인스턴스를 생성하지 않고 기명 클래스 표현식의 클래스 이름을 사용해 인스턴스를 생성하면 ReferenceError가 발생한다.
기명 함수 표현식과 마찬가지로 클래스 표현식에서 사용한 클래스 이름은 외부 코드에서 접근 불가능하다.