클래스(class) 는 ES6에 추가된 스펙
const User = function (name, age){
this.name = name;
this.age = age;
this.showName = function (){
console.log(this.name);
};
};
const mike = new User("Mike", 30);
// User {name: 'Mike', age: 30, showName: ƒ}
class User2 {
constructor(name, age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name);
}
}
const tom = new User2('tom', 19);
// User2 {name: 'tom', age: 19}
constructor
・ 클래스의 인스턴스 객체를 생성하고 초기화하는 특별한 메서드
・ 객체를 만들어주는 생성자 메서드
📍 생성자 함수
위의 예제에서 showName 이 객체
내부에 있다.
📍 class
위의 예제에서 showName 이 프로토타입(Prototype)
내부에 있다.
생성자 함수, class 모두 사용 방법은 동일하다.
mike.showName(); // Mike
tom.showName(); // tom
생성자 함수 가 클래스(class)와 같이 동작하도록 코드를 작성해 보자.
const User = function (name, age){ this.name = name; this.age = age; // this.showName = function (){ // console.log(this.name); // }; }; User.prototype.showName = function(){ console.log(this.name); } const mike = new User("Mike", 30); // User {name: 'Mike', age: 30}
위의 예제에서 new
를 제외하여 보자.
const mike = User("Mike", 30);
const tom = User2 ('tom', 19);
📍 생성자 함수
new
를 제외할 경우 리턴값이 없기 때문에 undefined
를 반환한다. 개발자의 실수가 있음에도 에러를 바로 발견할 수 없다.
📍 class
new
없이 사용할 경우 타입 에러가 발생한다.
📍 생성자 함수
프로토 타입의 showName 까지 모두 나온다.
for(const p in mike){
console.log(p)
}
// name
// age
// showName
📍 class
프로토 타입의 showName 은 보여 주지 않는다.
클래스 메서드는 for...in 문에서 제외된다.
for(const p in tom){
console.log(p)
}
// name
// age
🔗 for...in 반복문 복습하러 가기
🔗 [MDN] for...in 문 자세히 알기
클래스의 상속은 extends
키워드를 사용한다.
아래 예시를 보자.
class Car{
constructor(color){
this.color = color;
this.wheels = 4;
}
drive(){
console.log('drive...');
}
stop(){
console.log('stop!');
}
}
class Bmw extends Car {
park(){
console.log('park');
}
}
const z4 = new Bmw('blue');
클래스 내부에서 선언한 메서드는 프로토타입 내부로 들어간다.
bmw 내부에 car 에서 정의한 메서드와 같은 이름이 있을 땐 덮어 쓰기 가 된다.
super
키워드를 사용하면 된다.class Bmw extends Car {
park(){
console.log('park');
}
stop() {
super.stop();
console.log('off');
}
}
이렇게 하면 car 의 stop
메서드를 사용하게 된다.
이를 오버라이딩(overriding)이라고 한다.
class Car{
constructor(color){
this.color = color;
this.wheels = 4;
}
drive(){
console.log('drive...');
}
stop(){
console.log('stop!');
}
}
class Bmw extends Car {
constructor(){
this.navigation = 1;
}
park(){
console.log('park');
}
}
부모 생성자를 반드시 먼저 호출을 해야 한다는 에러가 발생한다.
클래스의 constructor
는 빈 객체를 만들어 주고 this
로 이 객체를 가르키게 된다.
반면 expends
로 만든 자식 클래스는 빈 객체가 만들어지고 this
에 할당하는 작업을 건너 뛰기 때문에 항상 super
키워드로 부모 클래스의 constructor
를 실행해 줘야 한다.
class Bmw extends Car {
constructor(){
super();
this.navigation = 1;
}
park(){
console.log('park');
}
}
단, 이 경우에도 color
값이 undefined
가 나오는 문제가 발생한다.
이를 해결하기 위해서는 자식 클래스의 constructor
에 동일한 인수를 받아야 한다.
class Bmw extends Car {
constructor(color){
super(color);
this.navigation = 1;
}
park(){
console.log('park');
}
}