March 31, 2021
this가 undefined
라고 합니다. 왜 이런 일이 발생할까요?
공식문서에 설명이 나와 있습니다.
Vue instance는 몇가지의 초기화 과정을 거칩니다. created, mounted 등의 생명주기 훅들은 this context가 Vue instance를 가리키도록 설정되고 나서 실행됩니다. 화살표 함수를 option property나 callback (created, watch … ) 에서 실행하지 말아야 합니다. 화살표 함수는 this를 가지고 있지 않기 때문에 this는 다른 변수들처럼 부모 스코프까지 렉시컬하게 조회되어
Uncaught TypeError: Cannot read property of undefined
나Uncaught TypeError: this.myMethod is not a function
같은 에러를 발생시킬 수 있습니다.
저는 여기서 Vue가 this context
를 어떻게 Vue instance
에 바인딩하는지 궁금해졌습니다. Vue core 코드를 뜯어보았습니다.
initMixin을 따라가봅니다.
initState가 data를 초기화하는 부분같습니다. initState를 따라갑니다.
data가 있으면 initData를 호출합니다. 따라들어갑니다.
data가 함수타입이면 getData를 실행합니다. 따라들어갑니다.
드디어 찾고있던 마지막 종착지입니다. data.call(vm,vm)
을 return합니다.
lifecycle hook의 경우에는 어떨까요?
init.js에서 callHook(vm, 'created')
를 따라갑니다.
invokeWithErrorHandling에 vm을 넘겨주고 있습니다.
똑같이 handler
에게 context
를 바인딩하면서 실행합니다.
예제를 만들어서 일반 함수와 화살표 함수의 동작원리를 비교해봤습니다. (Node.js 환경)
첫번째 예제에서는 this가 전부 전역 객체를 가리킵니다. ({})
두번째 예제에서는 생성자 함수로 객체를 만들어 바인딩해봤습니다. 화살표 함수의 경우 this context가 vm을 가리키지 못합니다.
call method의 첫번째 인자는 this, 두번째 인자부터는 함수의 매개변수로 값들이 전달됩니다. 화살표 함수도 vm을 잘 전달받습니다.
결론적으로, data에서 this를 사용하는 경우 화살표 함수를 쓰고 싶다면 vm을 인수로 넘겨줘야 하는데 굳이 이렇게까지 해서 화살표 함수를 쓰는 이점이 있을까? 라는 생각이 듭니다.
긴 글 읽어주셔서 감사합니다. 피드백은 언제나 환영입니다!