JS 중급 | 클래스 (Class)

uoah·2023년 2월 8일
0

자바스크립트

목록 보기
30/33
post-thumbnail

🚀 오늘의 학습 목표

  • 클래스(class)
  • 생성자 함수와 클래스의 차이
  • 클래스 상속
  • 메서드 오버라이딩
  • 컨스트럭터 오버라이딩

15. Class

클래스(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
・ 클래스의 인스턴스 객체를 생성하고 초기화하는 특별한 메서드
・ 객체를 만들어주는 생성자 메서드


15.1. Class 와 생성자 함수의 차이점

1. 메서드의 위치

📍 생성자 함수
위의 예제에서 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}

2. new 없이 실행 가능 여부

위의 예제에서 new 를 제외하여 보자.

const mike = User("Mike", 30);
const tom = User2 ('tom', 19);

📍 생성자 함수
new 를 제외할 경우 리턴값이 없기 때문에 undefined 를 반환한다. 개발자의 실수가 있음에도 에러를 바로 발견할 수 없다.

📍 class

new 없이 사용할 경우 타입 에러가 발생한다.

3. for...in 문 사용시

📍 생성자 함수
프로토 타입의 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 문 자세히 알기


15.2. Class 상속 (extends 키워드)

클래스의 상속은 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');

클래스 내부에서 선언한 메서드는 프로토타입 내부로 들어간다.


🔗 [MDN] extends 자세히 알기


15.3. 메서드 오버라이딩(method overriding)

bmw 내부에 car 에서 정의한 메서드와 같은 이름이 있을 땐 덮어 쓰기 가 된다.

❓ 부모 메서드를 그대로 사용하면서 확장하고 싶다면 super 키워드를 사용하면 된다.

class Bmw extends Car {
  park(){
    console.log('park');
  }
  stop() {
    super.stop();
    console.log('off');
  }
}

이렇게 하면 car 의 stop 메서드를 사용하게 된다.

이를 오버라이딩(overriding)이라고 한다.

15.4. 컨스트럭터 오버라이딩(constructor 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');
  }
}

0개의 댓글

관련 채용 정보