목차
JavaScript class 문법
자바스크립트에서는 객체 리터럴, 생성자 함수, Object.create()로 객체를 만들 수 있다. class는 공통 데이터와 메서드를 함께 정의하기 쉬운 문법이다. 내부적으로는 프로토타입 체인을 사용하므로, 클래스 문법을 이해할 때 이전 방식과의 관계를 함께 보면 좋다.
객체를 바로 만들기
원래 예시처럼 new Object()로 빈 객체를 만든 뒤 속성을 채울 수도 있다. 속성이 정해져 있다면 객체 리터럴이 더 간결하다.
const user = {
name: 'SeungCheol',
interests: ['Traveling', 'Swimming'],
greeting() {
console.log(`Hi! I'm ${this.name}.`);
}
};
user.greeting();
const userWithRole = {
get role() {
return 'Engineer';
}
};
console.log(userWithRole.role); // 메서드 호출 괄호 없이 읽는 접근자
greeting 안의 this는 호출한 객체를 가리킨다. get role()은 속성을 읽을 때 실행되는 getter다. 같은 데이터 구조의 객체를 여러 개 만들 때는 생성자 함수나 클래스를 사용할 수 있다.
생성자 함수와 프로토타입
function User(name, interests) {
this.name = name;
this.interests = interests;
}
User.prototype.greeting = function () {
console.log(`Hi! I'm ${this.name}.`);
};
const user3 = new User('Hello', ['Jump', 'Study']);
user3.greeting();
const user4 = Object.create(User.prototype, {
name: { value: 'Help' },
interests: { value: ['Travel', 'Jump'] }
});
user4.greeting();
new User(...)는 생성자 함수를 실행해 name과 interests를 설정한다. greeting은 User.prototype에 있으므로 인스턴스들이 같은 메서드를 공유한다. Object.create(User.prototype, ...)는 그 프로토타입을 가진 객체를 만들지만 User 생성자를 실행하지는 않는다. 필요한 속성을 별도로 제공해야 한다. Object.create() 문서에서 속성 설명자의 동작도 확인할 수 있다.
같은 구성을 class로 표현하기
class Usr {
constructor(name, interests) {
this.name = name;
this.interests = interests;
}
greeting() {
console.log(`Hi! I'm ${this.name}.`);
}
}
const usr1 = new Usr('Paik', ['Travel', 'Shopping']);
usr1.greeting();
console.log(Object.getPrototypeOf(usr1) === Usr.prototype); // true
constructor는 new Usr(...)에서 인스턴스를 초기화한다. greeting()은 각 인스턴스의 복사본이 아니라 Usr.prototype에 정의된다. class가 자바의 클래스와 똑같은 객체 모델을 새로 만드는 것은 아니다. MDN JavaScript 클래스 문서는 클래스를 프로토타입 기반 문법으로 설명한다.
하위 클래스를 만들 때는 extends를 사용한다. 하위 생성자에서 this를 사용하기 전에 super(...)로 부모 생성자를 호출해야 한다.
class Admin extends Usr {
constructor(name, interests) {
super(name, interests);
}
}
같은 객체 하나만 필요하면 리터럴로 충분하다. 여러 객체가 같은 초기화 규칙과 메서드를 공유해야 한다면 class가 코드를 읽기 쉽게 만든다.