클래스는 사실 함수이다. 프로토타입이 어색한 프로그래머를 위한 문법적 설탕이다.
클래스는 var 키워드로 선언한 변수처럼 호이스팅되지 않고 let, const 키워드로 선언한 변수처럼 호이스팅된다.
호이스팅은 var, let, const, function, function*, class 키워드를 사용한 모든 선언문에 적용된다.
const Foo = '';
{
// 호이스팅이 발생하지 않는다면 ''가 출력되어야 한다.
console.log(Foo);
// ReferenceError: Cannot access 'Foo' before initialization
class Foo {}
}
되도록이면 private을 사용하게 될 경우 nodejs환경에서 사용하거나
타입스크립트를 통해 접근제어자를 사용하자.
class Foo {
x = 1; // Field declaration
#p = 0; // Private field
static y = 20; // Static public field
static #sp = 30; // Static private field
bar() {
this.#p = 10; // private 필드 참조
// this.p = 10; // 새로운 public p 필드를 동적 추가한다.
return this.#p;
}
}
const foo = new Foo();
console.log(foo); // Foo {#p: 10, x: 1}
console.log(foo.x); // 1
// console.log(foo.#p); // SyntaxError: Undefined private field #p: must be declared in an enclosing class
console.log(Foo.y); // 20
// console.log(Foo.#sp); // SyntaxError: Undefined private field #sp: must be declared in an enclosing class
console.log(foo.bar()); // 10
extends
: 부모 클래스(base class)를 상속받는 자식 클래스(sub class)를 정의할 때 사용한다.
super
: 부모 클래스를 참조(Reference)할 때 또는 부모 클래스의 constructor를 호출할 때 사용한다.
// 부모 클래스
class Circle {
constructor(radius) {
this.radius = radius; // 반지름
}
// 원의 지름
getDiameter() {
return 2 * this.radius;
}
// 원의 둘레
getPerimeter() {
return 2 * Math.PI * this.radius;
}
// 원의 넓이
getArea() {
return Math.PI * Math.pow(this.radius, 2);
}
}
// 자식 클래스
class Cylinder extends Circle {
constructor(radius, height) {
// ① super 메소드는 부모 클래스의 constructor를 호출하면서 인수를 전달한다.
super(radius);
this.height = height;
}
// 원통의 넓이: 부모 클래스의 getArea 메소드를 오버라이딩하였다.
getArea() {
// (원통의 높이 * 원의 둘레) + (2 * 원의 넓이)
// ② super 키워드는 부모 클래스(Base Class)에 대한 참조
return (this.height * super.getPerimeter()) + (2 * super.getArea());
}
// 원통의 부피
getVolume() {
return super.getArea() * this.height;
}
}
참고
자바스크립트 기본