클래스 메서드를 구조화하는 방법

클래스 메서드를 구조화하는 방법

2022-10-01 last update

5 minutes reading typescript javascript

문제



다음 클래스가 있다고 가정합니다.

class Dog {
    numOfLegs = 4;

    getLegCount = function() {
        console.log(this.numOfLegs);
    }
}


이제 Dog 인스턴스가 있다고 가정해 보겠습니다.

const dog = new Dog();


다음과 같이 getLegCount 메서드를 호출할 수 있습니다.

dog.getLegCount();


예상대로 출력은 "4"가 됩니다. 하지만 Dog 객체를 구조화하면 어떻게 될까요?

const { getLegCount } = new Dog();


그에 따라 메서드에 대한 호출을 업데이트해 보겠습니다.

getLegCount();


출력이 동일할 것으로 예상할 수 있지만 대신 다음을 얻습니다.

Uncaught TypeError: this is undefined


왜 그럴까요? 클래스의 메서드를 구조화할 때 메서드의 this 컨텍스트가 더 이상 바인딩되지 않아 오류가 발생합니다.

해결책


this 컨텍스트를 어떻게 유지합니까? 두 가지 방법이 있습니다. 첫 번째 옵션은 this 컨텍스트의 바인딩을 클래스 생성자의 메서드에 명시적으로 설정하는 것입니다.

class Dog {
    constructor() {
        this.getLegCount = this.getLegCount.bind(this);
    }

    numOfLegs = 4;

    getLegCount = function() {
        console.log(this.numOfLegs);
    }
}


이렇게 하면 문제가 해결되고 예상대로 출력4됩니다.

두 번째 옵션은 화살표 함수를 사용하여 getLegCount 메서드를 정의하는 것입니다.

class Dog {
    numOfLegs = 4;

    getLegCount = () => {
        console.log(this.numOfLegs);
    }
}


이것 역시 this 컨텍스트의 문제를 해결하고 컨텍스트를 메서드에 명시적으로 바인딩할 필요 없이 그렇게 합니다. 종종 완전히 상호 교환 가능한 것으로 오해되지만 화살표 함수는 this에 대한 자체 바인딩이 없으므로 클래스의 this 컨텍스트를 닫는다는 점에서 기존 함수 표현식과 다릅니다.

이것은 클래스에 고유한this 컨텍스트가 있는 반면 객체의this 컨텍스트는 전역this 이라는 사실 때문에 기존 객체가 아닌 클래스에 대해서만 올바르게 작동합니다.

예를 들어 다음 객체가 있습니다.

const dog = {
    numOfLegs: 4,
    getLegCount: () => {
        console.log(this.numOfLegs);
    }
};


구조화되지 않은 메서드를 호출할 때:

const { getLegCount } = dog;


출력은 다음과 같이 표시됩니다.

undefined


결론



화살표 함수는 ES6 또는 ECMAScript 2015에 도입되었으므로 이전 레거시 시스템을 지원할 필요가 없거나 이전 버전과의 호환성을 보장하는 도구(예: Babel 또는 TypeScript)를 사용하는 한 화살표 함수는 좋은 접근 방식입니다. 어떤 접근 방식을 취하든 이제 () => {}function() {} 의 차이점에 대해 더 깊이 이해할 수 있습니다.