[JS/TS] static, class, instance

kyliecamila·2022년 2월 25일
0

JS/TS

목록 보기
1/1

class의 메소드나 프로퍼티에 static을 붙였을 때 class와 instance에서의 접근방법에 대해서 정리해보자

static이란

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 vs class이름

  1. 동일한 클래스 내의 정적 메소드에서 정적메소드를 호출한 경우
    => 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'
  1. 동일한 클래스 내의 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.';
  }
}
  1. 보통의 경우인 비정적 메소드에서 비정적 메소드를 호출한 경우
    => 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

0개의 댓글