"두 문법은 취향만 다른 것이 아니야. this를 누가 정하는지에 대해 서로 반대 결정을 해."
일반 함수의 this는 호출 방식이 정해
function으로 만든 함수의 this는 함수를 어떻게 호출했는지에 따라 달라져. obj.method()로 부르면 obj가 되고, 평범한 함수로 떼어 호출하면 엄격 모드에서 undefined가 될 수 있어. call, apply, bind로 명시적으로 정할 수도 있지.
이 성질은 객체의 메서드처럼 수신자가 중요할 때 유용해. 같은 함수라도 어느 객체의 동작으로 호출하는지에 따라 this가 달라져야 하니까. 대신 메서드를 값처럼 떼어 콜백에 넘기면 원래 수신자를 잃기 쉽다.
화살표 함수는 바깥 this를 붙잡아
화살표 함수는 자기 this를 만들지 않아. 정의된 자리의 바깥 this를 그대로 사용하고, 이후 call로 다른 값을 넘겨도 바뀌지 않아. 콜백 안에서 둘러싼 클래스 인스턴스나 객체 문맥을 유지하고 싶을 때 자연스러워.
반대로 객체 리터럴의 메서드를 화살표 함수로 만들면 obj.method()라고 불러도 this가 obj가 되지 않아. ‘메서드처럼 생겼으니 객체를 가리키겠지’라는 기대가 틀릴 수 있어. 수신자가 this가 되어야 하는 메서드는 일반 메서드 문법을 써.
클래스 메서드를 콜백으로 넘길 때
클래스의 일반 메서드는 prototype에 하나만 있고 인스턴스들이 공유해. 하지만 setTimeout(instance.method)처럼 넘기면 호출할 때 인스턴스가 사라질 수 있어. 화살표 함수로 감싸 () => instance.method()라고 하거나, 미리 bind하거나, 클래스 필드를 화살표 함수로 선언하는 방법이 있어.
화살표 필드는 인스턴스마다 새 함수가 만들어진다는 비용이 있어. 대부분 앱에서는 작지만 인스턴스가 아주 많다면 고려할 수 있어. 습관 하나로 모두 해결하려 하지 말고 호출 방식과 객체 수명을 보고 골라.