class
생성자 함수의 역할을 한다.
생성자 함수와 같이 파스칼케이스를 사용한다.
클래스를 선언하고 constructor라고 인스턴스를 뜻한다. class로 만든 자식이다.
클래스 몸체 안 에는 메소드만 선언 가능한다. constructor(생성자)메소드 내부에서만 클래스필드 선언과 초기화가 가능하다.
// 클래스 선언문
class Person {
// constructor(생성자) 이름을 바꿀 수 없다.
constructor(name) {
this._name = name;
// this는 클래스가 생성할 인스턴스(constructor)를 가리킨다.
// _name은 클래스 필드라 부른다.
}
sayHi() {
console.log(`Hi! ${this._name}`);
}
}
// 인스턴스 생성
// me 가 constructor 를 말한다. (인스턴스)
const me = new Person('Lee');
me.sayHi(); // Hi! Lee
console.log(me instanceof Person); // true
6.1 getter, setter
getter는 이름 그대로 무언가를 취득할 때 사용하므로 반드시 무언가를 반환해야 한다
class Foo {
constructor(arr = []) {
this._arr = arr;
}
// getter: get 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.
get firstElem() {
// getter는 반드시 무언가를 반환하여야 한다.
return this._arr.length ? this._arr[0] : null;
}
// setter: set 키워드 뒤에 오는 메소드 이름 firstElem은 클래스 필드 이름처럼 사용된다.
set firstElem(elem) {
// ...this._arr은 this._arr를 개별 요소로 분리한다
this._arr = [elem, ...this._arr];
}
}
const foo = new Foo([1, 2]);
// 클래스 필드 lastElem에 값을 할당하면 setter가 호출된다.
foo.firstElem = 100;
//foo._arr = [100,1,2]
console.log(foo.firstElem); // 100
8. 클래스 상속
새롭게 정의할 클래스가 기존에 있는 클래스와 매우 유사하다면, 상속을 통해 그대로 사용하되 다른 점만 구현하면 된다.
// 부모 클래스
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(radius);
this.height = height;
}
// 원통의 넓이: 부모 클래스의 getArea 메소드를 오버라이딩하였다.
getArea() {
// (원통의 높이 * 원의 둘레) + (2 * 원의 넓이)
return (this.height * super.getPerimeter()) + (2 * super.getArea());
}
// 원통의 부피
getVolume() {
return super.getArea() * this.height;
}
}
// 반지름이 2, 높이가 10인 원통
const cylinder = new Cylinder(2, 10);
// cylinder는 Cylinder 클래스의 인스턴스이다.
console.log(cylinder instanceof Cylinder); // true
// cylinder는 Circle 클래스의 인스턴스이다.
console.log(cylinder instanceof Circle); // true
// 부모 클래스
class Circle {
...
}
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() {
// ② super 키워드는 부모 클래스(Base Class)에 대한 참조
return super.getArea() * this.height;
}
}
// 반지름이 2, 높이가 10인 원통
const cylinder = new Cylinder(2, 10);
① super 메소드는 자식 class의 constructor 내부에서 부모 클래스의 constructor(super-constructor)를 호출한다. 즉, 부모 클래스의 인스턴스를 생성한다. 자식 클래스의 constructor에서 super()를 호출하지 않으면 this에 대한 참조 에러(ReferenceError)가 발생한다.
class Parent {}
class Child extends Parent {
// ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
constructor() {}
}
const child = new Child();