TIL 019 | JavaScript Class

JU CHEOLJIN·2021년 7월 10일
2

JavaScript

목록 보기
6/13
post-thumbnail

요즘 사람들 사이에서 와플 메이커가 유행이다. 크루아상 생지를 올려서 크로플을 만들기도 하고 삼각김밥이나 인절미 등을 통해서 삼각김밥 와플, 인절미 와플 등을 만들기도 한다. 여러가지를 뚝딱뚝딱 만드는 와플메이커 같은 역할을 할 수 있는게 바로 Class 이다.

Class

객체지향 프로그래밍이라는 말이 있다. 프로그램을 객체를 통해서 구성하고 각 객체들의 상호작용을 통해서 프로그램이 돌아갈 수 있도록 하는 것이다. 객체는 object 를 말하는데, 이에 대해서는 다음에 더 정리해보려고 한다.

class 는 객체지향 프로그래밍의 핵심 중에 하나라고 할 수 있다. object를 빠르고 쉽게 만들 수 있도록 도와주기 때문이다. class 의 경우에 ES6에서 새롭게 추가되었는데 프로토타입 기반의 JavaScript 에 아예 새로운 기능이 추가된 것이 아니라 함수의 일종으로 문법적인 편의성을 준 것이라고 생각하면 된다. 즉, syntactical sugar 라고 한다. 말 그대로 프로토타입 기반의 JavaScript를 사용하면서 객체지향 프로그래밍을 하기 위해 머리 아프지 말고 달콤하게 사용하라는 뜻이다.
(정말 감사합니다 😃😃😃)

Class declarations

// 기본 문법
class Person {
  // constructor
  constructor(name, age) {
    // fields
    this.name = name;
    this.age = age;
  }

  // methods
  speak() {
    console.log(`${this.name}: hello!`);
  }
}

위는 Person 이라는 class 를 만든 예시이다. classobject 를 만드는 역할을 하기 때문에 생성자(constructor)를 정의해 주어야 한다. 생성자는 말 그대로 만들려는 object 에 어떤 field 를 넣을 지를 결정한다. fieldobject 가 가질 정보라고 생각하면 된다.

마지막으로 method 의 경우에는 object 가 가지게 될 함수이다. 위에서는 간단하게 speak() 라는 함수를 넣어주었다.

구조를 보면 classobject 가 낯설지 않음을 느끼게 됐을 것이다. 간단하게 사람이라는 예시를 보자. 이 글을 쓰는 나는 이름으로 cheoljin 을 가지고 있고 성별로는 남자 를 가지고 있다. 가지고 있는 능력으로는 책읽기, 대화하기 등이 있다. 이를 클래스로 표현하면 아래와 같을 것이다.

class 한국사람 {
  constructor(이름, 성별){
    this.이름 = 이름;
    this.성별 = 성별;
  }
  책읽기(){
    책을 읽습니다.
  }
  대화하기(){
    대화를 합니다.
  }

임의로 한국남자 라는 class 를 생성했다. 여기에 몇가지 정보를 통해서 철진 이라는 object 를 만들 수 있다.

const 철진 = new 한국남자("철진", "남자");

방금 작업을 통해서 classinstance철진 이 만들어졌다. instanceclass 를 통해 생성된 object 를 뜻한다. 이처럼 classobject 는 현실의 물체들의 구조와 닮아있기 때문에 유용하게 사용될 수 있다.

Getter and setters

class 는 쉽게 여러 object 를 만들 수 있도록 해주기 때문에 매우 편리하다. 그런데, 누군가가 이 class 에 잘못된 정보를 넣어서 object 를 만든다면 어떻게 될까?

class 한국사람 {
  constructor(이름, 성별, 나이){
    this.이름 = 이름;
    this.성별 = 성별;
    this.나이 = 나이;
  }
  책읽기(){
    책을 읽습니다.
  }
  대화하기(){
    대화를 합니다.
  }

이런 class 가 있다고 해보자. 그런데 이를 사용하는 누군가가 마지막 필드인 나이에 -20이라는 숫자를 잘못 넣었다고 생각해보자. 그렇게 되면 나이가 -20인 말이 안되는 인스턴스가 생성될 것이다. 이런 일들을 방지하기 위해서 우리는 필드에 접근하느 경우에 제한을 걸 필요가 있다. 이 때 사용하는 것이 바로 gettersetter 이다.

class 한국사람 {
  constructor(이름, 성별, 나이) {
    this.이름 = 이름;
    this.성별 = 성별;
    this.나이 = 나이;
  }

  get 나이() {
    return this._나이;
  }

  set 나이(value) {
    // if (value < 0) {
    //   throw Error("나이는 0보다 작을 수 없습니다!!");
    // }
    this._나이 = value < 0 ? 0 : value;
  }
}

위를 보자. 생성자 아래에 getset을 작성했다. getsetaccesor property 로 값을 반환받거나 설정할 때 사용되는 함수이다.

차근차근 어떻게 사용되는지 살펴보자. 우선 get 의 경우에는 한국사람.나이 이 사용되는 경우에 호출이 되면서 나이를 반환해준다. 즉 한국사람.나이 를 사용했을 때 필드에 직접적으로 접근하게 되는 것이 아니라 get 나이() 가 실행된다는 뜻이다.

set 의 경우에는 한국사람.나이 = value 를 실행할 때 호출된다. 즉 값을 직접적으로 할당하는 것이 아니라 set 나이(value) 가 실행된다는 뜻이다. 그렇기 때문에 맞지 않는 값을 넣었을 때 에러 메세지를 보내거나 다른 값을 대신 넣도록 할 수 있다.

Inheritance

class 에는 또 다른 어썸한 능력이 있다. 바로 상속이다. 예를 들어 도형 이라는 클래스가 있다고 해보자. 이 도형이라는 클래스는 기본적으로 너비, 높이, 이라는 필드를 가지고 있고 그리기() 라는 메소드를 통해서 도형을 그려낼 수 있고 넓이() 라는 메소드를 통해 넓이 값을 구할 수 있다고 가정하자.

class 도형 {
  constructor(너비, 높이,) {
    this.너비 = 너비;
    this.높이 = 높이;
    this.=;
  }

  그리기() {
    
  }

  넓이() {
    return this.너비 * this.높이;
  }
}
  

이렇게 만들었다. 하지만 아직 아쉬운 점이 많다. 도형이라는 큰 클래스를 만들기는 했지만 사각형이나 삼각형, 붕어빵 모양 등의 도형을 만들고 싶을 때 바로 사용할 수 없기 때문이다. 각자의 특징에 맞게 만들고 싶다면 사각형이라는 클래스를 만들고 삼각형이라는 클래스를 또 만들고 붕어빵 클래스까지 만드는 작업을 반복해야 할 것이다. 하지만, 상속 덕분에 그런 작업을 반복하지 않아도 된다.

class 사각형 extends 도형 {}

짜잔! 🎉 방금의 동작을 통해 사각형의 class 가 생성됐다.

class 삼각형 extends 도형 {
  넓이(){
    return (this.너비 * this.높이)/2;
  }
}

이렇게 삼각형의 class 를 만들 수도 있다. 이 때, 넓이() 라는 메소드를 다시 정의해주었다. 삼각형의 경우에는 넓이를 구하는 방식이 다르기 때문이다.

이처럼 extends 를 통해서 class 를 상속시키는 경우에 메소드를 다시 정의해 주면서 다양성을 추구할 수 있고 특별히 선언하지 않은 경우에는 원형의 class 가 가지고 있던 필드나 메소드를 그대로 상속시킬 수 있다. 클래스는 정말 어썸하다✨

참고자료:
드림코딩 by 엘리

profile
사회에 도움이 되는 것은 꿈, 바로 옆의 도움이 되는 것은 평생 목표인 개발자.

0개의 댓글

관련 채용 정보