class

Class 문법으로 상속

  • extends 키워드 : 부모 클래스(base class)를 상속받는 자식 클래스(sub class)를 정의할 때 사용한다.
  • super 키워드 : super 키워드는 부모 클래스를 참조(Reference)할 때 또는 부모 클래스의 constructor를 호출할 때 사용한다.
// 부모 클래스

class Circle {

  constructor(radius) {

    this.radius = radius; // 반지름

  }

  // 원의 지름

  getDiameter() {

    return 2 * this.radius;

  }

  // 원의 둘레

  getPerimeter() {

    return 2 * Math.PI * this.radius;

  }

  // 원의 넓이

  getArea() {

    return Math.PI * Math.pow(this.radius, 2);

  }

}
// 자식 클래스

class Cylinder extends Circle {

  constructor(radius, height) {

    // ① super 메소드는 부모 클래스의 constructor를 호출하면서 인수를 전달한다.

    super(radius);

      this.height = height;

    }

    // 원통의 넓이: 부모 클래스의 getArea 메소드를 오버라이딩하였다.

    getArea() {

      // (원통의 높이 * 원의 둘레) + (2 * 원의 넓이)

      // ② super 키워드는 부모 클래스(Base Class)에 대한 참조

      return (this.height * super.getPerimeter()) + (2 * super.getArea());

    }

    // 원통의 부피

    getVolume() {

    // ② super 키워드는 부모 클래스(Base Class)에 대한 참조

      return super.getArea() * this.height;

    }

  }

  // 반지름이 2, 높이가 10인 원통

  const cylinder = new Cylinder(2, 10);

super가 메소드로 사용될 때

  • super 메소드는 자식 class의 constructor 내부에서 부모 클래스의 constructor(super-constructor)를 호출한다.
  • 즉, 부모 클래스의 인스턴스를 생성한다.
  • 자식 클래스의 constructor에서 super()를 호출하지 않으면 this에 대한 참조 에러(ReferenceError)가 발생한다.
class Parent {}

class Child extends Parent {

  // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

  // super 메소드를 호출하기 이전에는 this를 참조할 수 없음을 의미

  constructor() {}

}

const child = new Child();

super가 객체로 사용될 때

  • super 키워드는 부모 클래스(Base Class)에 대한 참조이다.
  • 부모 클래스의 필드 또는 메소드를 참조하기 위해 사용한다.

getter, setter

getter

  • 클래스 필드에 접근할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다.
  • 메소드 이름 앞에 get 키워드를 사용해 정의한다. 이때 메소드 이름은 클래스 필드 이름처럼 사용된다.
  • 호출하는 것이 아니라 프로퍼티처럼 참조하는 형식으로 사용하며 참조 시에 메소드가 호출된다.
  • 이름 그대로 무언가를 취득할 때 사용하므로 반드시 무언가를 반환해야 한다.

setter

  • 클래스 필드에 값을 할당할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다.
  • 메소드 이름 앞에 set 키워드를 사용해 정의한다.
  • 이때 메소드 이름은 클래스 필드 이름처럼 사용된다.
  • 호출하는 것이 아니라 프로퍼티처럼 값을 할당하는 형식으로 사용하며 할당 시에 메소드가 호출된다.
class Foo {

  constructor(arr = []) {

    this._arr = arr;

  }

  // getter: get 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.

  get firstElem() {

    // getter는 반드시 무언가를 반환하여야 한다.

    return this._arr.length ? this._arr[0] : null;

  }

  // setter: set 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.

  set firstElem(elem) {

    // ...this._arr은 this._arr를 개별 요소로 분리한다

    this._arr = [elem, ...this._arr];

  }

}

const foo = new Foo([1, 2]);

// 클래스 필드 lastElem에 값을 할당하면 setter가 호출된다.

foo.firstElem = 100;

console.log(foo.firstElem); // 100

getter와 setter는 클래스에서 새롭게 도입된 기능이 아니다. getter와 setter는 접근자 프로퍼티(accessor property)이다.

// _arr은 데이터 프로퍼티이다.

console.log(Object.getOwnPropertyDescriptor(foo, '_arr'));

// {value: Array(2), writable: true, enumerable: true, configurable: true}

// firstElem은 접근자 프로퍼티이다. 접근자 프로퍼티는 프로토타입의 프로퍼티이다.

console.log(Object.getOwnPropertyDescriptor(Foo.prototype, 'firstElem'));

// {get: ƒ, set: ƒ, enumerable: false, configurable: true}

Object.getOwnPropertyDescriptor(obj, prop)

매개변수

  • obj : 속성을 찾을 대상 객체
  • prop : 설명이 검색될 속성명

반환값

  • 객체에 존재하는 경우 주어진 속성의 속성 설명자, 없으면 undefined.

참고글

https://poiemaweb.com/es6-class

위의 사이트를 참고하여 class 문법에 대해 공부하였는데, 정말 정리가 잘 되어있다..!


Written by@Heaeun
코드리뷰, TDD, 함께 자라기를 지향하는 프론트엔드 개발자입니다

GitHub