[JS][ES6] 클래스
클래스 기본
ES6 버전부터는 자바스크립트에서도 클래스를 사용하여 객체를 생성할 수 있다. class 키워드와 함께 그 뒤에 클래스명을 지어 사용한다. 다음은 클래스 문법을 이용한 예제이다.
// 클래스 선언식
class Person {
constructor(name, age, phoneNumber) {
this.name = name;
this.age = age;
this.phoneNumber = phoneNumber;
}
showProfile() {
console.log("======= 개인 정보 =======");
console.log(`이름 : ${this.name}`);
console.log(`나이 : ${this.age}`);
console.log(`전화번호 : ${this.phoneNumber}`);
console.log("========================");
}
}
// class 문법으로 객체 생성 시, 반드시 new 키워드와 함께 사용해야함.
let james = new Person("James", 34, "1111-2222");
james.showProfile();
console.log(`클래스의 타입은? ${typeof Person}`);
// 클래스 표현식
let Mafia = class {
fireGun() {console.log("Bang!")}
};
new Mafia().fireGun();
======= 개인 정보 =======
이름 : James
나이 : 34
전화번호 : 1111-2222
========================
클래스의 타입은? function
Bang!
constructor() 는 생성자 메서드로, new 키워드와 함께 해당 클래스로부터 인스턴스를 생성하면 자동으로 생성자 메서드가 실행되어 새 객체를 초기화한다.
클래스 내부에서도 getter, setter 메서드를 그대로 사용할 수 있다.
클래스 필드 (class field)
객체 리터럴에서는 키:값 쌍으로 객체 프로퍼티를 정의하였다. 클래스 내부에서는 키 = 값의 형태로 클래스 내부에 프로퍼티를 추가할 수 있는데, 이 때 클래스 내부의 프로퍼티를 클래스 필드라 한다. 다음은 클래스 필드 예제이다.
function getAdd(a, b) {
return a + b;
}
class Person {
name = "James";
// 클래스 필드에는 표현식 및 함수 반환값도 저장 가능.
someMethod = function() {console.log("hi");}
number = getAdd(1, 2);
}
let james = new Person();
// 해당 객체의 클래스 필드에 접근.
console.log(james.name);
james.someMethod();
console.log(james.number);
James
hi
3
클래스 상속
자바스크립트에서는 클래스 상속을 위해 extends 키워드를 사용한다. 사용 형태는 다음과 같다.
class 자식클래스 extends 부모클래스
다음은 클래스 상속 사용 예이다. 클래스 상속 뿐만 아니라 메서드 오버라이딩, 생성자 오버라이딩도 다뤘다.
class Person {
constructor(name) {
this.name = name;
this.skill = undefined;
}
vote(target) {
this.target = target;
console.log(`${this.name}님이 ${this.target}님에게 투표하였습니다.`);
}
useSkill() {
let skillName = this.skill;
if (this.skill == undefined) {
skillName = "";
}
console.log(`${this.name}님이 ${skillName} 스킬을 사용하였습니다.`);
}
}
class Citizen extends Person {
chat(message) {
console.log(`[chat] ${this.name} : ${message}`);
}
}
class Mafia extends Person {
// constructor overriding
constructor(name) {
// super() : 부모 클래스의 생성자 호출. 자식 생성자 내부에서만 사용 가능.
// 자식 생성자 내부에서 this를 사용하기 전에 반드시 부모 생성자를 호출.
super(name);
this.skill = "밤에 시민 한 명 킬";
}
// Method overriding
useSkill() {
super.useSkill(); // super.method() : 부모 클래스의 메서드 호출.
console.log("누군가 밤에 살해당했습니다.");
}
}
let citizen = new Citizen("난무죄");
let mafia = new Mafia("갱스터");
citizen.vote("갱스터");
citizen.useSkill();
citizen.chat("난 저 사람 의심됨 ㅇㅇ.");
mafia.useSkill();
난무죄님이 갱스터님에게 투표하였습니다.
난무죄님이 스킬을 사용하였습니다.
[chat] 난무죄 : 난 저 사람 의심됨 ㅇㅇ.
갱스터님이 밤에 시민 한 명 킬 스킬을 사용하였습니다.
누군가 밤에 살해당했습니다.
생성자 오버라이딩
위 예제에서 보았듯, 자식 클래스에서 생성자를 오버라이딩하여 정의할 때, 내부에서 this 키워드를 사용하기 전에 반드시 super()를 통해서 부모 생성자를 먼저 호출, 초기화시키도록 해야 한다. 그렇지 않으면 에러가 발생한다.
부모 생성자에 매개변수가 있다면 자식 생성자 내부에서 부모 생성자 호출 시에도 super()
괄호 안에 해당 인자를 대입하는 게 좋다. 앞선 예제 3-1에서, Person을 상속받는 자식 클래스 Mafia의 생성자 내부에 super(name)
대신 super()라 해보면 this.name
은 초기화되지 않아 undefined가 저장된다. 실제로 해보면 undefined가 출력된다.
자식 생성자를 따로 정의하지 않으면 부모 생성자를 자동으로 호출한다. 따라서 자식 클래스 내부에선 마치 다음의 코드가 있는 것처럼 작동한다.
class Child extends Parent {
constructor(...args) {
super(...args);
}
}
instanceof
instanceof 연산자는 어떤 객체가 특정 클래스 타입인지 확인할 수 있는 연산자로, 그 결과로 boolean형 값이 반환된다. 사용 형태는 객체명 instanceof 클래스명
과 같이 사용한다.
다음은 여러 클래스들을 정의하고, 그로부터 생성된 인스턴스들에 대해 instanceof 연산자를 적용해본 예제이다.
class Person {}
class Citizen extends Person {}
class Bike {}
let p = new Person();
let c = new Citizen();
let bike = new Bike();
console.log(p instanceof Person);
console.log(c instanceof Citizen);
console.log(bike instanceof Person);
true
true
false
참고로, 상속 관계에 놓인 자식 클래스로부터 생성된 객체는 상위 클래스명과 함께 intanceof 연산자로 비교해도 true로 반환된다.
해당 연산자는 class 뿐만 아니라 생성자 함수에도 사용 가능하다고 한다.
References
[1] 클래스와 기본 문법
[2] 클래스 상속
This content is licensed under
CC BY-NC 4.0
댓글남기기