[JavaScript] 클래스(Class)

jjee·2025년 8월 22일

JavaScript

목록 보기
5/12

썸네일

클래스(Class)

JavaScript의 클래스(Class)에 대해 알아보자.

Class?

자바스크립트에서 클래스는 함수의 한 종류로, 동일한 종류의 객체를 여러 개 생성해야 할 때 사용하는 문법이다.
모던 자바스크립트에 도입된 클래스(class)라는 문법을 사용하면 객체 지향 프로그래밍에서 사용되는 다양한 기능을 자바스크립트에서도 사용할 수 있다.

기본 문법

기본적인 문법은 아래와 같다.

// Class 선언
class MyClass {
  // 여러 메서드를 정의할 수 있음
  
  // 생성자 메서드 - new 키워드를 사용하면 호출
  constructor() {
    // 객체의 기본 상태를 설정
    ...       
  }
  
  // 사용할 메서드
  method1() { ... }
  method2() { ... }
  
  ...
}

클래스 선언

Class 라는 예약어를 이용하여 객체를 만들기 위한 틀을 생성할 수 있는데, 이를 Class 선언이라고 한다.

// Class 선언
class Person {
  // 여러 메서드를 정의할 수 있음
  
  // 생성자 메서드 - new 키워드를 사용하면 호출
  constructor(name) {
    // 객체의 기본 상태를 설정
    this.name = name;
  }
}

인스턴스 만들기

만들어진 Class를 이용하여 인스턴스 객체를 만들 수 있다.
만약 Class 내부에 메서드가 있다면 메서드를 사용할 수 있다.

// 인스턴스 만들기
const user1 = new Person('hong'); // 생성자 호출

메서드 만들기

Class 내부에 함수를 메서드 형식으로 정의할 수 있다.
메서드는 객체가 가진 동작(기능)을 표현한다.

// Class 선언
class Person {
  constructor(name) {
    this.name = name;
  }
  
  // 메서드 정의
  sayHi() {
  	return `${this.name}: 안녕!`;
  }
}

메서드 내부에서 this.name은 해당 객체의 name 속성을 가리킨다.

메서드 사용하기

new 연산자를 통해 생성한 인스턴스 객체를 이용하여 내부 메서드를 사용할 수 있다.
생성된 객체에서 메서드를 사용하면 this는 그 객체 자신을 가리킨다.

const user1 = new Person('hong');
user1.sayHi(); // 메서드 사용

this

this는 메서드가 누구를 기준으로 실행되는지 결정한다.
클래스 안에서 this를 사용하면 this는 해당 인스턴스 객체를 의미한다.

const user1 = new Person("hong");
const user2 = new Person("gang");

console.log(user1.sayHi()); // "hong: 안녕!"
console.log(user2.sayHi()); // "gang: 안녕!"

예제

위의 내용을 합하여 예제를 만들어보자.

class Person {
  constructor(name) {
    this.name = name;
  }
 
  sayHi() {
  	return `${this.name}: 안녕!`;
  }
}

const user1 = new Person("hong");
const user2 = new Person("gang");
const user3 = new Person("lee");

console.log(user1.name); // "hong"
console.log(user2.name); // "gang"
console.log(user3.name); // "lee"

console.log(user1.sayHi()); // "hong: 안녕!"
console.log(user2.sayHi()); // "gang: 안녕!"
console.log(user3.sayHi()); // "lee: 안녕!"

상속?

클래스는 다른 클래스를 확장(상속)하여 재사용 할 수 있다.

A 클래스를 상속받은 B 클래스는 A 클래스의 기능을 모두 물려받으며,
물려받은 기능을 그대로 사용하거나 수정해서 사용(오버라이팅)할 수 있고, B 클래스만의 새로운 기능을 추가할 수도 있다.

extends

상속을 받기 위해서는 extends 키워드를 사용해야 한다.

class Animal {
  constructor(name) {
    this.name = name;
  }

  run() {
    console.log(`${this.name}이(가) 달림`);
  }

  speak() {
    console.log(`${this.name}이(가) 소리를 냄`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name}이(가) 강아지 소리를 냄`);
  }
  
  bark() {
    console.log(`${this.name}이(가) 멍멍!`);
  }
}

// 인스턴스 객체 생성
const puppy = new Dog("초코");

// 사용
puppy.run(); // "초코이(가) 달림"
puppy.speak(); // "초코이(가) 강아지 소리를 냄"
puppy.bark();  // "초코이(가) 멍멍!"

위의 예제에서 Dog 클래스는 Animal 클래스를 상속받는다.
Dog 클래스는 Animal 클래스가 가지고 있는 name 속성과 speak() 메서드를 그대로 사용할 수 있다.
또한 bark()라는 메서드를 추가로 생성하여 사용한다.

super

상속받은 클래스에서 constructor()를 쓰려면 constructor() 내부에서 가장 먼저 super()를 호출해야 한다.
이때 super()는 상속받는 클래스의 constructor()를 호출하는 역할을 한다.

class Cat extends Animal {
  constructor(name, color) {
    super(name);       // 부모의 constructor 호출
    this.color = color;
  }

  introduce() {
    console.log(`${this.color} 고양이 ${this.name}`);
  }
}

const kitty = new Cat("나비", "회색");
kitty.speak();      // "나비이(가) 소리를 냄"
kitty.introduce();  // "회색 고양이 나비"

메서드에서 오버라이딩을 구현하고 싶을 때도 super를 사용할 수 있다.

class Cat extends Animal {
  constructor(name, color) {
    super(name);       // 부모의 constructor 호출
    this.color = color;
  }
  
  run() {
    super.run();
    console.log(`고양이의 날쎈 모습!`);
  }

  introduce() {
    console.log(`${this.color} 고양이 ${this.name}`);
  }
}

const kitty = new Cat("나비", "회색");
kitty.run();      // "나비이(가) 달림 고양이의 날쎈 모습!"

클래스 필드?

constructor()에서 모두 설정하는 기존 방식 대신 클래스 안에서 속성(필드)을 바로 선언할 수 있다.
인스턴스를 만들면 자동으로 작성해둔 값이 들어간다.

class Person {
  name = "이름없음";

  sayName() {
    console.log(`이름: ${this.name}`);
  }
}

const user1 = new Person();
user1.sayName(); // "이름: 이름없음"

private 필드 사용하기

Class 외부에서 직접 접근할 수 없는 값을 만들고 싶을 때 필드명 앞에 #을 붙인다.
해당 값을 접근할 수 있는 메서드(getter/setter)를 만들어 사용할 수 있다.

class User {
  #password = "1234";

  checkPassword(input) {
    return input === this.#password;
  }
}

const user = new User();

console.log(user.#password); // ❌ 에러 발생
console.log(user.checkPassword("1234")); // true

#password 값은 외부에서 직접적으로 접근할 수 없으며, 수정할 수 없다.
필요한 경우 메서드를 통해 값에 접근할 수 있다.

getter/setter

#을 붙여서 만든 private 필드에 접근하기 위해서는 반드시 getter/setter 메서드를 사용해야 한다.
값을 불러오는 메서드를 getter, 값을 수정하는 메서드를 setter라고 한다.

class User {
  #password = "1234";

  // getter
  getPassword() {
    return this.#password;
  }

  // setter
  setPassword(pw) {
    this.#password = pw;
  }
}

const user = new User();

console.log(user.getPassword()); // "1234"
console.log(user.setPassword("4321"));
console.log(user.getPassword()); // "4321"

get/set 키워드를 이용하면 마치 객체의 프로퍼티에 접근하듯이 값을 다룰 수 있다.

class User {
  #password = "1234";

  // getter
  get password() {
    return this.#password;
  }

  // setter
  set password(pw) {
    this.#password = pw;
  }
}

const user = new User();

console.log(user.password()); // "1234"
user.password = "4321";
console.log(user.password()); // "4321"

get/set 키워드 사용시 메서드가 실행되는 것이 아닌 프로퍼티를 수정하는 것으로 오해를 불러일으킬 수 있다.
협업시에는 주석이나 가이드 문서를 이용하여 충분한 정보를 제공하는 것이 좋다.
또한 private 필드 선언을 한 프로퍼티의 경우 비공개임에도 불구하고 일반 프로퍼티와 같이 접근이 가능하게 되니 주의해야 한다.

언더바(_) 비공개 프로퍼티

#이 나오기 전에는 언더바(_)를 사용했다.
이 때 언더바(_)는 읽기 전용으로 사용하겠다는 표시로, 개발자간의 암묵적인 규약이었다.
JavaScript 자체의 강제성이 아니기 때문에 실제로는 수정이 가능한 변수이다.

정적 메서드와 정적 필드

정적 메서드와 정적 필드에 대해 알아보자.

static 키워드란?

static 키워드는 클래스 자체에 속하는 속성(필드)이나 메서드를 만들 때 사용한다.
속성(필드)이나 메서드의 앞에 static 키워드를 작성하면 된다.

공통 도구 함수(유틸리티)를 만들거나 인스턴스 없이 사용하는 전역 카운터 등을 만들 때 사용한다.
혹은 데이터 저장용 공간을 클래스 자체에 붙이고 싶은 경우에 사용할 수도 있다.

정적 메서드

new 없이 클래스 이름으로 바로 호출해서 사용할 수 있다.

class MathHelper {
  static add(x, y) {
    return x + y;
  }
}

console.log(MathHelper.add(2, 3)); // 5

static 키워드로 만들어진 값은 클래스 자체에 붙어있기 때문에 인스턴스 객체에서는 접근할 수 없다.

const helper = new MathHelper();

console.log(helper.add); // undefined

정적 필드

static 키워드를 필드에 붙이면 해당 필드는 외부에서 접근이 가능하다.
클래스 전체에 하나만 존재하는 값으로 인스턴스 객체 공유가 되지 않는다.

class Counter {
  static count = 0;

  static increase() {
    this.count++;
  }
}

Counter.increase();
Counter.increase();
console.log(Counter.count); // 2

참고

Class의 활용
클래스와 기본 문법
클래스 문법 시작하기

profile
내가 나에게 알려주는 개발 공부

0개의 댓글