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.
}
}