class의 메소드나 프로퍼티에 static을 붙였을 때 class와 instance에서의 접근방법에 대해서 정리해보자
static 키워드를 붙이면 class내의 메소드나 프로퍼티가
정적 메소드 / 정적 프로퍼티로 바뀌게 된다. (그렇게 정의 하게 되는 것이다)
class ClassWithStaticMethod {
static staticProperty = 'someValue';
static staticMethod() {
return 'static method has been called.';
}
static {
console.log('Class static initialization block called');
}
}
console.log(ClassWithStaticMethod.staticProperty);
// output: "someValue"
console.log(ClassWithStaticMethod.staticMethod());
// output: "static method has been called."
정적 메서드와 정적 프로퍼티는 클래스에 종속적이다.
클래스(붕어빵틀)에서 인스턴스(붕어빵)를 생성할 수 있는데
보통 클래스의 메서드와 프로퍼티는 특정 인스턴스와 연결되어있다.
하지만 정적 메서드와 정적 프로퍼티는 클래스와 연결되어있다.
그래서 정적 메소드/프로퍼티
는 클래스이름.메소드/프로퍼티
형식으로 사용해야하고 일반 메소드/프로퍼티
는 인스턴스 생성후 인스턴스이름.메소드/프로퍼티
형식으로 사용해야한다.
형식
정적 메소드/프로퍼티 :클래스이름.메소드/프로퍼티
일반 메소드/프로퍼티 :인스턴스이름.메소드/프로퍼티
//_instructor와 _numbers는 private로 설정해 두어서
//외부에서 접근이 불가하다.
//클래스이름.정적메소드(); 가능
const firstInstructor = Instructor.getInstance();
const secondInstructor = Instructor.getInstance();
//인스턴스.비정적메소드(); 가능
firstInstructor.addNumber(1);
secondInstructor.show();
//Instructor.addNumber(3); 불가
//Instructor.show(); 불가
//firstInstructor.getInstance(); 불가
class Instructor {
private static _instructor :Instructor;
private _numbers: number[];
private constructor(numbers:number[]){
this._numbers = numbers;
}
public static getInstance(): Instructor{
if(this._instructor==null){
this._instructor = new Instructor([]);
}
return this._instructor;
}
public addNumber(number:number){
this._numbers.push(number);
}
public show(): void{
for(const candidate of this._numbers){
console.log(candidate);
}
}
}
const firstInstructor = Instructor.getInstance();
const secondInstructor = Instructor.getInstance();
firstInstructor.addNumber(1);
secondInstructor.show();
//Instructor.addNumber(3); 불가
//Instructor.show(); 불가
//firstInstructor.getInstance(); 불가
- 동일한 클래스 내의
정적 메소드에서 정적메소드
를 호출한 경우
=>this
class StaticMethodCall {
static staticMethod() {
return 'Static method has been called';
}
static anotherStaticMethod() {
return this.staticMethod() + ' from another static method';
}
}
StaticMethodCall.staticMethod();
// 'Static method has been called'
StaticMethodCall.anotherStaticMethod();
// 'Static method has been called from another static method'
- 동일한 클래스 내의 constructor를 비롯한
비정적 메소드에서 정적메소드
를 호출한 경우
=>class이름
class StaticMethodCall {
constructor() {
console.log(StaticMethodCall.staticMethod());
// 'static method has been called.'
console.log(this.constructor.staticMethod());
// 'static method has been called.'
}
static staticMethod() {
return 'static method has been called.';
}
}
- 보통의 경우인
비정적 메소드에서 비정적 메소드
를 호출한 경우
=>this
class Bird{
static readonly _wingNumber : number=2;
private _species :String;
//비정적에서 비정적 호출
constructor(species:String){
this._species = species;
}
//비정적에서 비정적 호출
species():String {
return this._species;
}
//비정적에서 정적 호출
wingNumber(): number{
return Bird._wingNumber;
}
//정적에서 정적 호출
static showWingNumber(): number{
return this._wingNumber;
}
}
정적 메서드와 정적 프로퍼티는 인스턴스와는 연결되어 있지 않기에 인스턴스를 만들때 사용되는 클래스의 데이터를 가져오지 못한다.
// 클래스 데이터 접근 예제
class Person {
constructor() {
this._name = "내이름은";
}
static get name(){
return this._name
}
}
// 1. 정적 메서드를 이용해 클래스 데이터 가져오기 - 실패
console.log(Person.name) // undefined
// 2. 클래스 인스턴스를 선언해 클래스 데이터 가져오기 - 실패
const person = new Person();
console.log(person.name) // undefined
참고자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes/static
https://velog.io/@hchayan/1.-JS-static-%ED%82%A4%EC%9B%8C%EB%93%9C