Javascript의 class는 객체(Object)와 관련이 있다.
객체를 직접 작성하여 정의하고 생성할 수도 있지만, 클래스로 만들어주면 여러 객체를 더 쉽게 만들 수 있다.
클래스는 객체를 생성하기 위한 템플릿이다.
class를 통해 원하는 구조의 객체 틀을 짜놓고, 비슷한 모양의 객체를 공장처럼 찍어낼 수 있다.
쉽게 생각해서 클래스 = 붕어빵 기계, 그리고 객체 = 붕어빵 으로 보면 된다.
JavaScript는 prototype기반의 객체지향 프로그래밍 언어이다.
그렇다면 JS에 왜 class가 추가된 것이고 왜 사용하는 걸까?
ES6부터 추가된 class는 직관적으로 쉽게 코드를 읽을 수 있게 만들어 줄 뿐만 아니라, 작성하기도 쉽고 또 class 기반 언어에 익숙한 개발자가 더 빠르게 적응할 수 있다.
function Me(name) {
this.name = name;
}
Me.prototype.wow = function () {
console.log("WOW!");
};
let person = new Me("Jason");
person.wow(); // WOW!
class
class Me {
constructor(name){
this.name = name;
}
wow(){
console.log("WOW!");
}
}
let person = new Me("Jason");
person.wow() // WOW!
class Korean {
constructor(name, age) {
this.name = name;
this.age = age;
this.country = 'Korea';
}
addAge(age) {
return this.age + age;
}
}
let kim = new Korean("KIMJINYOUNG",24);
{
name: 'KIMJINYOUNG',
age: 24,
country: 'Korea',
addAge: function(age){
return this.age + age;
}
}
Korean 클래스를 이용해 kim 객체를 만들면 위와 같은 instance가 생성된다.
class Cat {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
return `${this.name} is eating!`
}
meow() {
return 'MEOWWWW'
}
}
class Dog {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
return `${this.name} is eating!`
}
bark() {
return 'WOOF'
}
}
이 두 개의 클래스를 보면 살짝 다르지만 여전히 복제된 기능들이 많은데,
JavaScript에서 가능한 옵션 중 하나가 바로 이 복제된 코드를 이 Cat이나 Dog에서 두 클래스가 모두 확장시킬 수 있는 따로 만든 별개의 클래스로 이동시키는 것이다.
일종의 부모와 자식 관계라고 생각하면 된다.
class Pet {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
return `${this.name} is eating!`
}
}
class Cat extends Pet {
meow() {
return 'MEOWWWW'
}
}
class Dog extends Pet {
bark() {
return 'WOOF'
}
}
이처럼 extend 키워드를 사용하면 자식 클래스인 Dog에서 부모 클래스인 Pet의 값을 사용할 수 있다.
let boksil = new Dog("Boksil",5);
boksil.eat() // Boksil is eating!
Dog 클래스를 살펴보면, 분명 eat 메소드와 constructor 메소드가 없는데도 eat 메소드를 사용할 수 있다.
그렇다면 Dog에도 eat 메소드를 추가해준다면?
class Dog extends Pet {
bark() {
return 'WOOF'
}
eat() {
return `${this.name} is happy!`
}
}
let boksil = new Dog("Boksil",5);
boksil.eat() // Boksil is happy!
바로 Dog 버전의 eat을 출력한다.
만약 Dog의 프로토타입에서 eat을 찾지 못하면 Pet에서 찾게 되니까 이렇게 찾아낸 것이다.
부모 클래스의 값을 상속받고, 추가적으로 자식만의 값을 사용하고싶다면 super 키워드를 사용할 수 있다.
class Pet {
constructor(name, age) {
console.log('IN PET CONSTRUCTOR!')
this.name = name;
this.age = age;
}
eat() {
return `${this.name} is eating!`
}
}
class Cat extends Pet {
constructor(name, age, livesLeft = 9) {
console.log('IN CAT CONSTRUCTOR!')
super(name, age)
this.livesLeft = livesLeft;
}
meow() {
return 'MEOWWWW'
}
}
const monty = new Cat('monty',9);
// IN CAT CONSTRUCTOR!
// IN PET CONSTRUCTOR!
console.log(monty); // Cat {name: 'monty', age: 9, livesLeft: 9}
monty를 살펴보면 name이 monty이고, age는 9살에 livesLeft는 9로 설정되어 있다.
super 키워드를 사용해 부모 클래스의 constructor (Pet의 생성자)에서 온 기능을 재사용했지만, Cat에 따로 하나를 추가한 것이다.