클래스 (Class))

Posted by Seongkyun Yu on 2020-03-15
Estimated Reading Time 5 Minutes
Words 807 In Total
Viewed Times

클래스란?

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

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


구분 Class 생성자 함수
인스턴스 생성 O O
super 호출 O X
extends O X
new 미사용 에러 O X
암묵적 strict mode O X
메소드[[Enumerable]] X O



클래스의 정의 방법과 특징

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

class.js
1
2
3
4
5
6
7
class Person {} // 클래스 선언문

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

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

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

특징:

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

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

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



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

1. constructor

constructor.js
1
2
3
4
5
6
7
class Person {
// 생성자
constructor(name) {
// 인스턴스 생성 및 초기화
this.name = name;
}
}

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

특징:

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

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

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


2. 프로토타입 메소드

prototype.js
1
2
3
4
5
6
7
8
9
10
11
12
class Person {
// 생성자
constructor(name) {
// 인스턴스 생성 및 초기화
this.name = name;
}

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

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


3. 정적 메소드

static.js
1
2
3
4
5
6
7
8
9
10
11
12
class Person {
// 생성자
constructor(name) {
// 인스턴스 생성 및 초기화
this.name = name;
}

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

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



프로퍼티

1. 접근자 프로퍼티

property.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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(" ");
}
}

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


2. Private

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

private.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
// private 필드 정의
#name = "";

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

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

3. Static 필드

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

staticField.js
1
2
3
4
5
6
7
8
9
10
11
12
class MyMath {
// static public 필드 정의
static PI = 22 / 7;

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

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

4. 클래스 필드

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

classField.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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' ]



상속에 의한 클래스 확장

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

1. extends 키워드

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

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

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

extends
1
2
3
4
5
6
7
8
function Base1() {}

class Base2 {}

let condition = true;

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

2. super 키워드

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

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


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

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

super.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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 클래스의 정적 메소드를 가리킨다.
staticSuper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !