들어가며
자바스크립트는 객체지향 언어입니다. 객체끼리 상호작용하며 프로그램이 동작한다는 것이죠. 자바스크립트는 이러한 객체지향을 프로토타입을 통해 구현합니다. 이는 여타 객체지향 언어들에서 클래스 문법을 사용하는 것과는 상반되죠.
ES5 버전까지의 자바스크립트는 클래스 문법을 지원하지 않았습니다. 하지만 다른 클래스 기반 객체지향 프로그래밍에 익숙한 프로그래머들의 언어 스위칭과 직관적인 프로그래밍을 위해 ES6에서 클래스가 도입되게 됩니다.
이 클래스는 어떤거고 어떻게 사용하는 걸까요? 지금부터 간단하게 알아보도록 하겠습니다.
본론
클래스 정의하기
클래스는 기본적으로 키워드 class를 사용하여 정의할 수 있습니다.
class Rectangle {}
위 중괄호 안, 클래스 몸체라고 부르는 부분에는 세 가지 메서드를 정의할 수 있습니다.
- 생성자 - constructor
- Prototype 메서드
- static 메서드
class Rectangle {
// 생성자
constructor(height, width) {
// 이곳에서 인스턴스 생성 및 초기화가 진행됩니다.
this.height = height;
this.width = width;
}
// Prototype 메서드
calcArea() {
return this.height * this.width;
}
// static 메서드
static displayName = "Rectangle";
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
인스턴스 생성하기
인스턴스는 new 연산자와 함께 클래스를 호출하여 생성할 수 있습니다.
const square = new Rectangle(10, 10);
여기서 주의하셔야 할 점은, 함수 같은 경우에는 new 연산자의 유무에 따라 일반 함수/생성자 함수의 분기로 호출되지만, 클래스는 인스턴스 생성만을 위해 존재하기에 new 연산자를 반드시 붙여야 합니다. 붙이지 않으면 런타임 에러가 발생하게 됩니다.
constructor
constructor는 인스턴스를 생성하고 초기화하는 메서드입니다. 생성자 함수와 유사해 보이지만 차이점이 있습니다.
- constructor는 클래스에 한 개씩만 존재할 수 있습니다.
- class에서 constructor는 생략할 수 있습니다.
인스턴스 생성 시 외부에서 인스턴스 프로퍼티의 초기값을 전달하려면 constructor에 매개변수를 선언하고 인스턴스 생성 시 초기값을 전달합니다. 이 초기값이 constructor의 매개변수에 전달됩니다.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
const square = new Rectangle(5, 5); // 5, 5가 각 height, width로 전달됩니다.
또한 constructor는 별도의 return을 갖지 않아야 합니다. 이는 생성자 함수와 동일하게 new 연산자를 통해 생성자 함수 실행 시 암묵적으로 this(인스턴스)를 반환하기 때문입니다. 만약 여기 return이 있으면 암묵적으로 반환해야 할 인스턴스가 아닌 return문에 적힌 것을 반환하기에 절대 constructor에는 return을 작성해서는 안됩니다.
Prototype 메서드
프로토타임 메서드 추가를 위해서는 명시적으로 클래스 내에 메서드를 추가하면 됩니다.
class Rectangle {
...
// Prototype 메서드
calcArea() {
return this.height * this.width;
}
}
static 메서드
정적(static) 메서드는 인스턴스를 생성하지 않아도 호출할 수 있는 메서드입니다.
class Rectangle {
...
// static 메서드
static displayName = "Rectangle";
}
Rectangle.displayName // "Rectangle"
접근자 프로퍼티
접급자 프로퍼티는 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티입니다.
class Rectangle {
constructor() {
this._width = 0;
this._height = 0;
}
get width() {
return this._width;
}
set width(value) {
this._width = value;
}
get height() {
return this._height;
}
set height(value) {
this._height = value;
}
}
const myRectangle = new Rectangle();
// width와 height 속성 설정
myRectangle.width = 10;
myRectangle.height = 20;
// 속성 값 출력
console.log(myRectangle.width); // 10
console.log(myRectangle.height); // 20
getter는 인스턴스 프로퍼티에 접근 시마다 프로퍼티 값을 조작하거나 별도의 행위가 필요할 때 사용합니다. 메서드 앞에 get 키워드를 붙여 정의할 수 있습니다. 비슷하게 setter는 인스턴스 프로퍼티에 값을 할당할 때마다 프로퍼티 값을 조작하거나 별도의 행위가 필요할 때 사용합니다. get과 마찬가지고 set 키워드를 붙여 정의할 수 있습니다. getter, setter는 마치 인스턴스의 프로퍼티처럼 사용됩니다. 호출이 아니라 참조하는 형식으로 사용하여 참조 시 내부적으로 호출되는 것이죠. getter는 반드시 무언가를 반환해야 합니다. 반대로 setter는 반드시 매개변수가 있어야 합니다.
상속
자바스크립트 클래스 상속은 extends 키워드를 사용합니다. 아래는 그 예시입니다.
// 부모 클래스 (슈퍼 클래스)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}이/가 소리를 냅니다.`);
}
}
// 자식 클래스 (서브 클래스)
class Dog extends Animal {
constructor(name, breed) {
super(name); // 부모 클래스의 생성자 호출
this.breed = breed;
}
bark() {
console.log(`${this.name}이/가 짖습니다.`);
}
}
// 자식 클래스의 인스턴스 생성
const myDog = new Dog('멍멍이', '골든 리트리버');
// 부모 클래스의 메서드 호출
myDog.speak(); // 출력: 멍멍이이/가 소리를 냅니다.
// 자식 클래스의 메서드 호출
myDog.bark(); // 출력: 멍멍이이/가 짖습니다.
상속을 받아 확장된 클래스를 서브클래스, 서브클래스에 상속된 클래스를 수퍼클래스라고 부릅니다.
마치며
지금까지 자바스크립트의 클래스 문법에 대해 간단하게 살펴보았습니다. 이번에 살펴본 내용 외에 클래스의 내부적인 인스턴스 생성과정, 프로토타입 체이닝 등 많은 부분이 제외되었지만 기본적으로 클래스 문법을 이해할 수 있도록 생략하였습니다. 하지만 이번 기회로 알게 된 클래스, 조금 더 알아보는 것은 어떨까요? 자바스크립트 뿐 아니라 다른 언어를 배울 때 러닝 커브를 확실하게 줄일 수 있는 좋은 방법이라고 생각합니다!