클래스는 객체를 생성하는 템플릿입니다. 클래스를 설명하면서 붕어빵 이야기를 많이 하죠. 붕어빵을 만들려면 붕어빵을 찍어내는 틀이 있어야 합니다. 이 틀을 바로 클래스라고 하며, 클래스를 통해 찍어낸 실제 붕어빵을 객체의 인스턴스라고 합니다.
클래스 정의하기
자바스크립트에서는 두 가지 방식 1) 클래스 선언식과 2) 클래스 표현식으로 클래스를 정의할 수 있습니다.
클래스 선언식 (Class declarations)
클래스 선언식은 클래스를 정의하는 방법 중 하나이며, class
키워드와 함께 클래스 이름을 지정합니다. 이때 이름의 첫 문자는 대문자로 적어주는 것이 컨벤션입니다.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
참고로 함수 선언과 클래스 선언의 차이점은 함수는 선언 전에 호출할 수 있지만 클래스는 컨스트럭트(constructed) 전에 반드시 선언되어야 한다는 것입니다. 다음과 같은 코드는 ReferenceError
를 발생시킵니다.
const p = new Rectangle(); // ReferenceError
class Rectangle {}
이는 클래스가 호이스팅될 때 값이 초기화되지 않았기 때문입니다.
클래스 표현식 (Class expressions)
클래스 표현식은 클래스를 정의하는 또 다른 방법입니다. 클래스 표현식은 이름을 갖거나 갖지 않을 수 있습니다. 그러나 표현식에 이름이 없더라도 name
속성을 통해 접근할 수는 있습니다.
// 이름 없는 표현식
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rctangle.name); // "Rectangle"
// 이름이 있는 표현식
Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.widt = width;
}
};
console.log(Rectangle.name); // "Rectangle2"
클래스 바디와 메소드 정의
클래스의 바디는 중괄호 {}
안에 담깁니다. 여기에 클래스의 구성 요소인 컨스트럭터와 메소드를 정의할 수 있습니다.
컨스트럭터 (Constructor)
컨스트럭터 메소드는 객체를 생성하고 class
를 통해 생성된 객체를 실행하는 메소드입니다.
class Polygon {
constructor() {
this.name = 'Polygon';
}
}
const poly1 = new Polygon();
console.log(poly1.name);
// expected output: "Polygon"
하나의 클래스 내에는 단 하나의 constructor
라는 이름의 메소드만 존재할 수 있습니다. 다른 곳에서 constructor
메소드를 중복해서 사용하면 SyntaxError
가 발생합니다.
컨스트럭터는 super
키워드를 사용하여 슈퍼 클래스의 컨스트럭터를 호출할 수 있습니다.
프로토타입 메소드 (Prototype methods)
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
제너레이터 메소드
class Polygon {
constructor(...sides) {
this.sides = sides;
}
// Method
*getSides() {
for (const side of this.sides) {
yield side;
}
}
}
const pentagon = new Polygon(1,2,3,4,5);
console.log([...pentagon.getSides()]); // [1, 2, 3, 4, 5]
스태틱 메소드와 속성
static
키워드를 사용하여 클래스의 스태틱 메소드 또는 클래스를 정의할 수 있습니다. 스태틱 요소들은 클래스의 인스턴스화 없이 호출할 수 있으며, 클래스의 인스턴스를 통해서는 호출할 수 없습니다. 스태틱 메소드는 애플리케이션의 함수를 생성하는 데 사용되는 반면, 스태틱 속성은 캐시, 고정 설정값, 복사할 필요가 없는 값을 선언할 때 사용됩니다.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static displayName = "Point";
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance; // undefined
p2.displayName; // undefined
p2.distance; // undefined
console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755
인스턴스 속성
인스턴스 속성은 반드시 클래스 메소드 내에서 이뤄져야 합니다.
class Retangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
필드 선언
퍼블릭 필드 선언
자바스크립트 필드 선언 문법에 따라 위의 코드는 아래와 같이 작성할 수 있습니다. 이때, 필드를 선언하기 위해 let
, const
, var
와 같은 키워드는 필요 없습니다.
class Rectangle {
height = 0;
width;
constructor(height, width) {
this.height = height;
this.width = width;
}
}
프라이빗 필드 선언
클래스 필드는 기본적으로 퍼블릭이지만 다음과 같이 #
을 사용하여 프라이빗 필드를 선언할 수 있습니다.
class Rectangle {
#height = 0;
#with;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}
프라이빗 필드를 클래스 외부에서 참조하면 에러가 발생합니다. 이는 클래스 바디 내에서만 읽고 쓸 수 있습니다.
extends
를 사용한 서브 클래싱
extends
키워드를 사용하여 클래스의 자식을 생성할 수 있습니다. 이를 통해 자식 클래스는 부모 클래스의 메소드를 사용할 수 있습니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // // call the super class constructor and pass in the name parameter
}
speak() {
console.log(`${this.name} barks.`);
}
}
const d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
서브 클래스 내에 constructor
가 있는 경우, this
를 사용하기 전에 super()
를 호출해야 합니다.
참고 자료
'개발 > JavaScript' 카테고리의 다른 글
자바스크립트 디데이 계산하기 (0) | 2023.01.04 |
---|---|
자바스크립트 Set 설명 (0) | 2022.11.01 |
자바스크립트 Promise, async, await 정리 (0) | 2022.10.20 |