클래스는 함수다. 또한 클래스도 일급객체다
function Player(name){
this.name = name;
this.notice = function(name){
alert(this.name);
}
}
class Player{
constructor(name){
this.name = name;
}
notice(){
alert(this.name);
}
}
let pro = new Player('Caps')
클래스 몸체에는 0개 이상의 메서드만 정의할 수 있다.
메서드로는 constructor(생성자), 프로토타입 메서드, 정적메서드 3가지가 있다.
그렇다면 생성자 함수와 클래스의 정의 방식 차이는?
정의 방식은 형태적인 면에서는 유사하다.
이렇게 보면 constructor 가 헷갈린다.
- 클래스의 constructor 메서드와 프로토타입 constructor 프로퍼티는 이름은 같지만 직접적인 관련이 없다.
- 프로토타입 constructor 프로퍼티 = 모든 프로토타입이 가진 프로퍼티이며 생성자 함수를 가리킨다.
만약 위 그림에서 정적메서드를 호출하려면?
- 생성자 함수의 경우
Person.sayHello(); //Hello
- 클래스의 경우 (Person 클래스로 호출)
만약 인스턴스로 호출한다면 타입 에러 발생Person.sayHello(); //Hello
생성자 함수 vs 클래스
- 클래스와 생성자 함수 모두 프로토타입 기반의 인스턴스를 생성하지만 정확히 동일하게 동작하지 않는다.
- 클래스는 생성자 함수보다 엄격하며 생성자함수에서 제공하지 않는 기능도 제공한다.
- 클래스는 new연산자 없이 호출하면 에러 / 생성자 함수는 일반함수로 호출된다.
- 클래스는 상속을 지원하는 extends와 super 키워드 제공
- 클래스는 호이스팅이 발생하지 않는 것처럼 동작 / 함수 선언문으로 정의된 생성자 함수는 함수호이스팅이, 함수표현식으로 정의했다면 변수호이스팅 발생
- 클래스 내의 모든 코드는 암묵적으로 strict mode 가 지정되어 실행된다.
- 클래스의 constructor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]]값이 false다. 즉 열겨할 수 없다.
아래의 그림을 통해 상속에 대한 개념을 더욱 쉽게 알아보자
class Animal{
constructor(age,weight){
this.age = age;
this.weight = weight;
}
eat(){return "Eat";}
move(){return "Move";}
}
//상속을 통해 Animal 클래스를 확장한 Bird 클래스
class Bird extends Animal{
fly(){return "Fly";}
}
const bird = new Bird(1, 5);
console.log(bird) //Bird {age:1, weight:5}
console.log(bird.eat()) // Eat
console.log(bird.fly()) // Fly
extends 키워드
- 상속을 통해 클래스 확장시 사용되는 키워드
- extends 키워드 앞에는 반드시 클래스가 와야한다.
super 키워드
- super 호출시 부모 클래스의 constructor를 호출한다. ex) super();
- super 참조시 수퍼 클래스의 메서드를 호출 할 수 있다. ex) super.sayHi();
- 주의 사항
1) 서브 클래스에서 constructor를 생략하지 않으면 서브 클래스의 constructor에서는 반드시 super를 호출 해야한다.
2) 서브 클래스의 constructor에서 super를 호출하기 전에는 this를 참조할 수 없다. 즉 this보다 앞에서 호출 되어야 한다.
3) super 는 반드시 서브클래스의 constructor 에서만 호출 해야한다.
class Polygon {
constructor(height, width) {
this.name = 'Polygon';
this.height = height;
this.width = width;
}
sayName() {
console.log('Hi, I am a ', this.name + '.');
}
}
class Square extends Polygon {
constructor(length) {
this.height; // 참조오류가 발생합니다. super가 먼저 호출되어야 합니다.
// 여기서, 부모클래스의 생성자함수를 호출하여 높이값을 넘겨줍니다.
// Polygon의 길이와 높이를 넘겨줍니다.
super(length, length);
// 참고: 파생 클래스에서 super() 함수가 먼저 호출되어야
// 'this' 키워드를 사용할 수 있습니다. 그렇지 않을 경우 참조오류가 발생합니다.
this.name = 'Square';
}
get area() {
return this.height * this.width;
}
set area(value) {
this.area = value;
}
}
출처 및 참고 : MDN
아직 부족한 내용들이 많다. 조금 더 보충해야 겠다.
그래도 대략적인 생성자 함수와 클래스, 인스턴스의 관계를 파악할 수 있게 되었다.