티스토리 뷰

 

자바스크립트를 이용하여 웹 개발 또는 객체지향화된 클래스를 개발하는 과정에서 흔히 발생할 수 있는 문제 중 하나는 콜백 함수를 등록할 때 발생하는 인스턴스 자신을 가리키는 참조 변수인 this를 참조할 수 없는 문제입니다.

 

예를 들어, 다음과 같이 class A를 선언하고 setTimeout 함수를 이용해 인스턴스의 메서드를 호출하는 경우가 있습니다. (이는 가장 간단한 예시들 중 하나일 뿐입니다)

 

class A {
    constructor(value) {
        this.value = value;
        setTimeout(this.handle, 100);
    }

    handle() { console.log(this.value); }
}

 

위 코드에서는 setTimeout 함수에 this.handle을 전달하여 100ms 이후에 handle 메서드가 호출되도록 하고 있습니다. 그러나 실행 결과는 예상과 달리 undefined를 출력합니다.

 

이렇게 의도치 않은 상황이 생긴 이유는 setTimeout 함수의 콜백 함수가 실행될 때, 그 함수의 컨텍스트(여기서는 window 객체, 또한 컨텍스트는 호출하는 주체를 의미합니다.) 내에서 호출되기 때문에 this가 제대로 인스턴스를 가리키지 못하는 것입니다. 이를 해결하기 위해서는 콜백 함수 내에서의 this를 명시적으로 지정해주어야 합니다.

 

가장 간단한 해결 방법은 화살표 함수(arrow function)을 이용하는 것입니다. 화살표 함수는 자신의 this를 갖지 않고, 외부의 스코프에서 this를 물려받습니다. 따라서 아래와 같이 handle 메서드를 화살표 함수로 래핑하면 예상대로 동작하게 됩니다.

 

setTimeout(() => this.handle(), 100);

 

하지만 이러한 방식은 한가지 문제점이 생길 수 있습니다. 위 코드에서의 문제점은 함수를 호출하는 주체는 외부 스코프로 한정될 수 밖에 없습니다.

 

// this.handle.bind(other_object)
setTimeout(this.handle = this.handle.bind(other), 100);

 

따라서 일부 객체를 주체로 정의하려면 위 코드에서와 같이 bind 함수를 호출하여 주어진 객체가 호출하는 주체가 되도록 할 수 있습니다.