클래스

Seongkyun Yu·2020년 12월 7일
0

TIL - Javascript

목록 보기
21/28

기존 블로그에 작성한 내용을 velog로 이전한 글입니다


1. 클래스란?

객체지향 언어의 class를 자바스크립트에서 사용하게 해주는 문법적 설탕이라고 할 수 있다.

하지만 클래스가 생성자 함수와 완전히 같지는 않다.


구분Class생성자 함수
인스턴스 생성OO
super 호출OX
extendsOX
new 미사용 에러OX
암묵적 strict modeOX
메소드[[Enumerable]]XO


2. 클래스의 정의 방법과 특징

정의 방법과 인스턴스 생성 방법은 다음과 같다.

class Person {} // 클래스 선언문

const Person = class {}; // 익명 클래스 표현식

const Person = class MyClass {}; // 기명 클래스 표현식

const me = new Person(); // 인스턴스 생성

특징:

  1. 클래스는 함수로 평가되며 일급 객체이다.

  2. 클래스는 constructor, static, 프로토타입 메소드를 쓸 수 있다.

  3. let, const와 마찬가지로 호이스팅이 일어나지 않는 것처럼 보인다.



3. 클래스에서 사용하는 메서드

3.1. constructor

class Person {
  // 생성자
  constructor(name) {
    // 인스턴스 생성 및 초기화
    this.name = name;
  }
}

인스턴스를 생성하고 초기화 할 때 쓰인다.

특징:

  1. constructor는 클래스 내에 최대 한개만 쓸 수 있다. (어길시 SyntaxError 발생)

  2. 쓰지 않더라도 암묵적으로 빈 객체를 반환하게 consturctor를 사용한다.

  3. return을 명시적으로 쓴다면 원시값은 무시, 객체는 반환한다.


3.2. 프로토타입 메소드

class Person {
  // 생성자
  constructor(name) {
    // 인스턴스 생성 및 초기화
    this.name = name;
  }

  // 프로토타입 메소드
  sayHi() {
    console.log(`Hi! My name is ${this.name}`);
  }
}

생성자 함수처럼 prototype을 통해 명시하지 않아도 프로토타입 메소드가 된다.


3.3. 정적 메소드

class Person {
  // 생성자
  constructor(name) {
    // 인스턴스 생성 및 초기화
    this.name = name;
  }

  // 정적 메소드
  static sayHi() {
    console.log("Hi!");
  }
}

인스턴스를 생성하지 않고 쓸 수 있는 메소드는 static을 활용하여 정적 메소드로 활용하는 것이 좋다.



4. 프로퍼티

4.1. 접근자 프로퍼티

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  // fullName은 접근자 함수로 구성된 접근자 프로퍼티이다.
  // getter 함수
  get fullName() {
    return this.firstName + " " + this.lastName;
  }

  // setter 함수
  set fullName(name) {
    [this.firstName, this.lastName] = name.split(" ");
  }
}

생성자 함수와 마찬가지로 접근자 함수를 사용할 수 있다.


4.2. Private

최신 사양의 브라우저(Chrome 74 이상)와 최신 Node.js(버전 12 이상)에서 private한 변수를 사용할 수 있다.

class Person {
  // private 필드 정의
  #name = "";

  constructor(name) {
    // private 필드 참조
    this.#name = name;
  }

  // name은 접근자 프로퍼티이다.
  get name() {
    // private 필드를 참조하여 trim한 다음 반환한다.
    return this.#_name.trim();
  }
}

4.3. Static 필드

static메소드 이외에 static 필드는 최신 사양의 브라우저(Chrome 74 이상)와 최신 Node.js(버전 12 이상)에서 사용할 수 있다.

class MyMath {
  // static public 필드 정의
  static PI = 22 / 7;

  // static private 필드 정의
  static #num = 10;

  // static 메소드
  static increment() {
    return ++MyMath.#num;
  }
}

4.4. 클래스 필드

클래스 필드에 변수 선언시 인스턴스 프로퍼티가 된다.

class Person {
  // 클래스 필드에 선언시 최신 버전 nodejs나 브라우저에서 작동, 인스턴스 프로퍼티가 되지만 this를 이용한 초기화 불가
  legend = "WooooW";

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

  sayProfile() {
    console.log(`이름: ${this.name}
    나이: ${this.age}`);
  }
}

const me = new Person("yu", 32);

console.log(Object.getOwnPropertyNames(me)); // [ 'legend', 'name', 'age' ]

console.log(Object.getOwnPropertyNames(Person)); // [ 'length', 'prototype', 'name' ]



5. 상속에 의한 클래스 확장

생성자 함수와 달리 클래스는 다른 생성자 함수나 클래스를 상속 받아 확장할 수 있다.

5.1. extends 키워드

extends 사용하여 클래스나 생성자 함수를 상속받을 수 있다.

단 좌항에는 반드시 클래스가 와야 한다.

extends는 [[Construct]] 내부 메소드를 갖는 함수 객체를 반환하는 표현식을 사용할 수 있다.

function Base1() {}

class Base2 {}

let condition = true;

// 조건에 따라 동적으로 상속 대상을 결정하는 서브 클래스
class Derived extends (condition ? Base1 : Base2) {}

5.2. super 키워드

  • 호출시(super()) : 수퍼 클래스(상위 클래스)의 constructor 실행

    반드시 constructor 안에서 호출해야 한다.


  • 참조시 : 수퍼 클래스(상위 클래스)의 메소드 사용

    축약 표현된 메소드 안에서면 super참조 사용이 가능하다

class Person {
  // 클래스 필드에 선언시 최신 버전 nodejs나 브라우저에서 작동, 인스턴스 프로퍼티가 되지만 this를 이용한 초기화 불가
  legend = "WooooW";

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

  sayProfile() {
    console.log(`이름: ${this.name}
    나이: ${this.age}`);
  }
}

class Man extends Person {
  constructor(name, age, hp, mp) {
    super(name, age); // 반드시 super 호출로 상위 클래스 초기화를 마쳐야함
    this.hp = hp;
    this.mp = mp;
  }

  goGym() {
    console.log("운동하느라 체력이 감소했다", this.hp, "-->", --this.hp);
  }
}

const me = new Man("Yu", 32, 200, 200);

console.log(me); // Man { legend: 'WooooW', name: 'Yu', age: 32, hp: 200, mp: 200 }

me.goGym(); // 운동하느라 체력이 감소했다 200 --> 199

me.goGym(); // 운동하느라 체력이 감소했다 199 --> 198

  • 서브클래스의 정적 메소드 내에서 super 참조는 super 클래스의 정적 메소드를 가리킨다.
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  static sayProfile() {
    console.log(`super의 정적 메소드`);
  }
}

class Man extends Person {
  static sayProf() {
    super.sayProfile();
  }
}

Man.sayProf(); // super의 정적 메소드

참고자료: poiemaweb.com

profile
FrontEnd Developer

0개의 댓글