JavaScript와 Class

특성

상속

super

부모 클래스의 constructor를 호출하기 위해 사용하는 메서드.

static

클래스 레벨에 속하는 변수 및 메서드를 선언하고 싶을 때 사용한다.
클래스 자체에 속하기 때문에(인스턴스에 속하는 것이 아님), 해당 클래스로부터 파생된 인스턴스에서 모두 불러올 수 있으며, 인스턴스를 생성하지 않아도 접근할 수 있다.
또한 메모리에 한 번만 할당되기 때문에 메모리 공간을 절약할 수 있다는 장점이 있다.

static 변수클래스 변수
메모리에 한 번만 할당인스턴스가 생성될 때마다 메모리에 할당
클래스를 통해서 접근 가능인스턴스를 통해서 접근 가능
class Sample {
  static sVariable = "S";
  variable = "V";
 
  getVariable() {
    this.sVariable;  // 접근 불가
    this.variable;  // 접근 가능
 
    Sample.sVariable;  // 접근 가능
    Sample.variable;  // 접근 불가
  }
}
 
Sample.sVariable;  // "S"
Sample.variable;  // 접근 불가
 
new Sample().sVariable  // 접근 불가
new Sample().variable  // "V"

또한 static 변수는 클래스 단위에서 공유되기 때문에, 특정 인스턴스에서 static 변수의 값을 수정했을 때 다른 인스턴스도 영향을 받는다.

class Sample {
  static sVariable = "S";
  
  change() {
    Sample.sVariable = "T";
  }
  
  get() {
    return Sample.sVariable;
  }
}
 
const a = new Sample();
a.get();  // S
a.change();
a.get();  // T
 
const b = new Sample();
b.get();  // T

전역변수의 예기치 않은 오염은 예측 불가능한 실행 결과를 야기할 수 있으므로, readonly를 키워드를 이용하여 함부로 수정될 수 없도록 사용하는 것이 바람직할 것이다.
(readonly 키워드는 TypeScript에서 사용할 수 있다)

TypeScript를 이용한 class 이용

this

메서드 내 this를 사용할 경우, this가 바인딩 되는 객체는 메서드를 실행시키는 인스턴스가 된다.
(. 앞에 위치한 객체가 바인딩 된다)

이러한 특성은 다음과 같은 결과를 낳는다.

class User {
  name: string;
 
  constructor(name: string) {
    this.name = name;
  }
  
  info() {
    return this.name;
  }
}
 
const user1 = new User("Tim");
const copy = { copyInfo: user1.info };
 
console.log(copy.copyInfo());  // undefined

copy 변수에 할당된 객체의 copyInfo에는 User 클래스 info 메서드가 할당된다.
. 앞에 위치한 객체에는 this가 바인딩 되기 때문에, copyInfo 메서드가 참조하는 this는 copy 객체가 된다.
이때 copy 객체는 name이라는 속성을 가지고 있지 않기 때문에 undefined가 반환된다.

TypeScript에서는 this의 타입을 명시적으로 선언함으로써, 프로퍼티의 존재 여부를 체크할 수 있다.
이를 통해, 참조할 수 없는 프로퍼티를 런타임 이전에 발견할 수 있다.

class User {
  name: string;
 
  constructor(name: string) {
    this.name = name;
  }
  
  info(this: User) {  // 메서드의 인자로 클래스의 타입을 가진 this를 명시적으로 선언한다
    return this.name;
  }
}
 
const user1 = new User("Tim");
const copy = { copyInfo: user1.info };
 
console.log(copy.copyInfo());  // Error. Property 'name' is missing

간단하게 초기화하기

인스턴스를 생성하는 과정에서 constructor 함수의 파라미터로 여러 개의 인자를 넣어야 될 때의 클래스 선언은 다음과 같다.

class User {
  private name: string;
  private age: number;
 
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

만약 constructor 함수에 들어가야 하는 파라미터의 개수가 많을 경우, 코드가 길어지고 복잡해지는 단점이 있는데, 이를 해결하기 위해 다음과 같이 약식으로 표현할 수 있다.

class User {
  constructor(private name: string, private age: number) {
    this.name = name;
    this.age = age;
  }
}

읽기 전용

readonly 키워드를 이용한다.

class User {
  constructor(private readonly name: string, private age: number) {
    this.name = name;
    this.age = age;
  }
  
  edit(name: string) {
    this.name = name;  // Cannot assign to 'name' because it is a read-only property.
  }
}