프로그래밍프론트엔드 개발자

타입스크립트 클래스 메서드에서 일반 함수와 화살표 함수 사용 시 this의 타입화 메커니즘은 어떻게 작동하나요? 주의사항과 모범 사례를 설명하세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

타입스크립트에서 클래스 내부의 메서드에 대한 this 타입은 기본적으로 현재 클래스 인스턴스를 나타냅니다. 그러나 메서드를 화살표 함수로 정의하면 this의 컨텍스트는 호출 시점이 아닌 선언 시점에 바인딩됩니다.

일반 메서드:

class Counter { value = 0; increment() { this.value++; } }

화살표 함수:

class Counter { value = 0; increment = () => { this.value++; } }

주요 사항:

  • 일반 메서드는 콜백으로 전달될 때 this의 컨텍스트를 잃습니다(예: 이벤트 리스너에서).
  • 화살표 함수는 선언된 클래스의 컨텍스트를 유지하지만 프로토타입에 보이지 않으며, 각 인스턴스를 위해 생성됩니다.
  • 추가적인 검사를 위해 메서드 시그니처에서 this 타입을 명시적으로 지정할 수 있습니다:
class Foo { bar(this: Foo) { // ... } }

함정 질문.

increment()increment = () => {}의 차이는 무엇인가요? 콜백으로 사용할 때 this의 컨텍스트에 어떤 영향을 미치나요?

틀린 답변:

  • "클래스의 필드와 메서드에는 차이가 없으며, 타입스크립트가 자동으로 처리합니다."

올바른 답변:

  • 일반 메서드의 this 컨텍스트는 호출 시점에 결정됩니다. 메서드를 함수로 전달하면: setTimeout(counter.increment, 0), 이 경우 thisundefined(엄격 모드) 또는 window(비엄격 모드)가 됩니다. 반면 화살표 함수는 자신의 환경을 유지합니다:
class Demo { value = 1; inc() { console.log(this.value); } incArrow = () => { console.log(this.value); } } const d = new Demo(); setTimeout(d.inc, 0); // undefined 또는 오류 setTimeout(d.incArrow, 0); // 1

이 주제에 대한 무지로 인한 실제 오류 사례.


이야기

반응형 프레임워크 프로젝트에서 클래스 메서드가 명시적 bind 없이 콜백으로 직접 전달되었습니다. 이로 인해 this가 undefined가 되어 this 속성 접근 시 오류가 발생하여 애플리케이션이 중단되었습니다. 이 문제는 메서드를 화살표 함수로 다시 작성하거나 명시적으로 bind하여 해결했습니다.


이야기

개발자가 메서드에서 this의 타입을 명시했지만, 해당 메서드 내 화살표 함수의 타입화는 잊어버렸습니다. 결과적으로 중첩된 콜백 내부의 this는 클래스 인스턴스가 아닌 window를 가리켰습니다. 팀은 상태 유출 문제에 직면하여 이벤트 아키텍처를 변경해야 했습니다.


이야기

큰 UI 컴포넌트가 애플리케이션을 느리게 만든 이유는 모든 메서드가 클래스의 화살표 필드로 정의되어 있었기 때문입니다(new Counter().increment = ...). 이로 인해 각 인스턴스에 대해 새로운 함수 복사본이 생성되어 일반 메서드와 같이 프로토타입에 대한 하나의 정의가 아니었습니다. 이로 인해 메모리 소비가 증가하고 최적화가 필요했습니다.