오늘은 클래스에 대해 알아보도록 한다.
원래 자바스크립트 언어는 우리를 힘들게 하는 프로토타입 기반의 언어이다. 하여 이전 ES5에서는 프로토타입을 통해 생성자 함수와 객체지향 언어를 구현할 수 있었다!
이후 등장한 클래스(aka. 붕어빵틀)는 생성자 함수와 매우 유사하게 동작한다.
하지만 우리가 알아야 할 몇가지 차이점이 있다!
클래스는 생성자 함수 보다 견고하고 명료하다(하지만 우월하진 않다, 상황에 따라 다르게 사용!) "객체를 만드는 새로운 방법"이라고 생각하자
클래스를 정의하는 방법
//클래스 선언문
class 붕어빵틀 {}
//클래스 표현식 (익명)
const 붕어빵틀 = class {};
//클래스 표현식 (기명)
const 붕어빵틀 = class MyClass {};
지난번에 알아본 함수와 같이 클래스도 일급 객체이다! 그래서..
1. 런타임에 생성이 가능하다
2. 변수나 자료구조(배열, 객체 등)에 저장할 수 있다
3. 함수의 반환값으로 사용 가능하다
클래스의 호이스팅
class 붕어빵틀 {}
console.log(typeof 붕어빵틀); // function
클래스는 함수로 평가된다 (typeof 찍었을 때).
선언문은 런타임 이전에 먼저 평가되어 함수 객체를 생성한다.
클래스 선언문으로 클래스를 만든 경우, 런타임 이전에 평가되어서 함수 객체를 생성하는데.. 여기서의 함수 객체는 생성자함수로 호출할 수 있는 constructor이다.
이와 동시에 프로토타입도 함께 생겨난다고 한다..!
여기서 논란의 호이스팅 문제
console.log(잉어빵틀); // 선언하기 전 참조 안되는것 처럼 보임
class 잉어빵틀 {}
참조에러로 호이스팅 안되는 것 처럼 보이지만 let const 와 같은 변수처럼 호이스팅이 된다. 일시적 사각지대에 빠져 호이스팅이 발생하지 않는 것처럼 동작하는 것이다.
인스턴스 생성
//되는 것 (일반적인 방법)
class 붕어빵틀 {}
//인스턴스 만들기
const 팥붕어빵 = new 붕어빵틀();
console.log(팥붕어빵); // 붕어빵틀 출력
//안되는 것 (에러발생)
// 기명 클래스 표현식의 클래스 이름을 사용해 인스턴스를 생성하면 에러가 생긴다
const 팥붕어빵 = class 붕어빵틀 {};
const 슈붕어빵 = new 팥붕어빵 {};
console.log(붕어빵틀);
const 녹차붕어빵 = new 붕어빵틀();
메서드
클래스의 몸체에는세 가지 메서드를 정의할 수 있다.
1. constructor
constructor는 인스턴스를 생성하고 초기화하기 위한 특수한 메서드!
class Jiyun {
//생성자
constructor(name) {
//인스턴스 생성 및 초기화
this.name = name;
}
}
const person = new Jiyun('marie');
console.dir(person);
클래스 내부의 prototype 프로퍼티 안 constructor 프로퍼티가 있고, constructor는 자신을 가리키고 있다.
놀라운 사실:
*클래스의 constructor 메서드와 프로토타입의 constructor 프로퍼티는 직접적인 관련이 없다. (?????)
프로토타입의 constructor 프로퍼티는 생성자 함수를 가리킨다.
우리가 기억 할 것:
class Banana {
constructor(){
}
}
const apple = new Banana();
console.log(apple); //Banana {}
//위처럼 빈객체를 생성함!!!
class Room {
constructor(chair, table){
this.chair = chair;
this.table = table;
}
}
const myroom = new Room('red', 'blue');
console.log(myroom);
2. 프로토타입 메서드
// 생성자 함수
function Jiyun(name){
this.name = name;
}
Jiyun.prototype.sayHi = function () {
console.log(`Hi my name is ${this.name}`);
};
const jiyunone = new Jiyun('june');
jiyunone.sayHi();
3. 정적 메서드
class Room {
constructor(chair, table){
this.chair = chair;
this.table = table;
}
}
Room.sayColor = function() {
console.log('Hi!');
};
// 정적 메서드 호출
Room.sayColor(); // Hi
프로토타입 메서드? 정적 메서드? 기억할 것
class Square {
constructor(width, height){
this.width = width;
this.height = height;
}
//프로토타입 메서드
area() {
return this.width * this.height;
}
}
const square = new Square(10, 10);
console.log(square.area()); // 100