본문 바로가기
이론/Frontend

JavaScript의 클래스 (Class of JavaScript)

by 유세지 2021. 9. 11.

이번 시간에는 자바스크립트의 클래스 개념에 대해 알아보겠습니다. 객체지향 프로그래밍에서 클래스는 빼놓을 수 없는 개념이지만, 자바스크립트의 객체 체계는 이러한 클래스의 개념과 그리 잘 맞는 체계는 아니었습니다. 실제로 자바스크립트에 class라는 키워드가 명세에 추가된 것도 ES6가 되고 나서부터입니다. 결국 다른 언어들에서 지원하는 클래스와 자바스크립트의 클래스는 모양만 비슷할 뿐, 그 내부는 전혀 다른 방식으로 동작하고 있다는 것이죠.

 

사실 너무나 흔한 개념이라 인지하지 못하고 있는 경우가 많지만, 클래스 또한 디자인 패턴의 일종입니다. 처음부터 객체지향 프로그래밍을 염두한 자바와 같은 언어는 클래스가 모든 설계의 기본이 되는 개념이지만, 절차적 프로그래밍을 지원하는 다른 코드에선 딱히 클래스를 사용하지 않더라도 프로그램이 돌아가는데에는 문제가 없습니다. 대표적으로 우리에게 친숙한 자바스크립트PHP 같은 언어들이 그 예시입니다. 심지어 C++도 그렇습니다.

 

결국 자바스크립트에서 클래스를 사용할지, 아닐지는 본인의 선택입니다. 특히 대형 서비스를 유지하고 개발하는 입장이 아니라면, 사실 객체지향은 그다지 효율적인 방법이 아닐지도 모르겠습니다. 그렇지만 분명 중요한 개념이고 프로그래밍을 직업으로 삼는다면 꼭 필요한 부분인 것은 확실히 논쟁의 여지가 없습니다. 

 

그럼 자바스크립트의 클래스가 가진 요소들을 한 번 살펴봅시다.

 

 

클래스 구조

class Person {
  name;
  age;
  #code;

  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  getName() {
    console.log(this.name);
  }
}

자바스크립트의 클래스 구조입니다. public 필드인 name, age와 private 필드인 code가 있고, name과 age를 인자로 받는 생성자 constructor가 존재하며 자신의 이름을 콘솔에 출력하는 getName() 메소드도 가지고 있는 가장 기본적인 클래스 모양입니다. 여타 클래스처럼 생성자는 constructor라는 이름으로 하나만 존재하고, 부모는 super 키워드를 통해서 접근할 수 있습니다.

 

몇 가지 주의할 점은 클래스는 함수와 다르게 호이스팅이 되지 않습니다. 따라서 클래스 선언은 반드시 호출보다 상위에 자리해야합니다. 또한 클래스는 재정의 될 수 없습니다. 만약 재정의를 시도한다면 SyntaxError가 발생하게 됩니다.

 

public, private 필드의 경우 일부 브라우저에서는 작동하지 않을 수 있습니다. 자세한 내용은 MDN 문서를 참고해주세요.

 

 

 

참고로 이 아래에 나오는 예시 코드들은 위의 Person 클래스가 정의되어 있다는 가정하에 작성됩니다.

 

 

상속

상속은 클래스를 만드는 가장 큰 이유입니다. 자식 클래스는 부모/조상 클래스의 속성이나 메소드들을 물려받고, 거기에 필요한 기능들을 추가하거나 수정하여 사용할 수 있습니다. 그래서 부모 클래스는 추상화되어있고, 자식 클래스는 이를 구체화한다고 표현합니다.

 

이 때 자식 클래스가 부모 클래스로부터 가져온 메소드를 수정하여 전혀 새로운 방식으로 작동시키는 것을 오버라이드라고 합니다. 이처럼 같은 이름의 변수나 메소드가 상황에 따라 다르게 해석되는 것이 다형성의 특징입니다.

 

class Student extends Person {
  constructor(name, age) {
    super(name, age); // super class 생성자를 호출하여 name, age 매개변수 전달
  }
  
  study() {
    console.log("study hard!");
  }
}

let kim = new Student('Kim', 18);
kim.name(); // "Kim"
kim.study(); // "study hard!"

 

Student 클래스가 extends 키워드를 통해 Person 클래스를 상속받는 예시입니다. 여기서 자식 클래스는 Student, 부모 클래스는 Person 이라고 할 수 있습니다.

 

Student 클래스는 super 키워드를 통해 부모인 Person 클래스의 생성자를 가져와서 사용합니다. 또한 기존에 존재하지 않던 study() 메소드도 추가되었습니다. 추상화 되어있던 부모의 개념이 자식으로 상속되며 확장된 모습입니다.

 

C++ 같은 일부 언어에서는 한 자식 클래스가 여러 부모 클래스를 가지는 다중 상속을 지원하기도 합니다. 하지만 자바스크립트는 다중 상속을 지원하지 않기 때문에 주의해야합니다.

 

 

믹스인

자바스크립트는 다중 상속을 지원하지는 않지만, 여러 클래스의 메소드들을 가져오고 싶은 경우가 존재할 수 있습니다. 이럴때 사용하는 것이 믹스인입니다. 믹스인은 특정 행동을 실행해주는 메서드를 제공하는 객체입니다. 단독으로는 쓰이지 않고, 다른 클래스에 행동을 더해주는 용도로 사용되는 것들을 통칭합니다.

 

타겟 클래스에 믹스인 해주기 위해서는 Object.assign() 을 이용해 속성들을 복사해줍니다.

 

let Mixin = {
  introduce() {
    console.log(`I'm ${this.name}, ${this.age} old.`);
  }
};

Object.assign(Person.prototype, Mixin);

new Person('Kim', 20).introduce(); // I'm Kim, 20 old.

 

이런식으로 Mixin 객체의 내용들을 새로 만든 Person 인스턴스에 복사해주면, introduce() 메소드를 사용할 수 있게 됩니다. 같은 방법으로, 다양한 믹스인 객체에서 원하는 기능만을 골라 가져올 수 있습니다.

 

한 가지 주의할 점은 Object.assign()의 타겟이 Person이 아닌 Person.prototype 이어야 합니다. 아직 프로토타입에 대한 개념을 모르신다면 아리송 하실 수 있는데, Person.prototype에는 Person이 상속받은 메소드들이 정의되어 있습니다. 프로토타입에 관한 자세한 내용은 다음 글에서 다루겠습니다.

 

 

 

마치며

오늘은 자바스크립트의 클래스에 관한 내용들을 살펴보았습니다. 다른 객체지향적 언어들과 어떤 차이점이 있고, 클래스를 사용하려면 어떻게 해야하는지 등등의 내용들을 다루어보았는데요. 다음 글에서는 이러한 클래스의 구현과 밀접한 관련이 있는 프로토타입에 대해 알아보겠습니다.

 

긴 글 읽어주셔서 감사합니다.

반응형

댓글