Vue.js 화살표 함수(arrow function) 주의점

Vue.js의 data 및 lifcecycle hook(created, mounted…)에서 화살표 함수를 사용하면 어떻게 될까요?

image

image

this가 undefined라고 합니다. 왜 이런 일이 발생할까요?

공식문서에 설명이 나와 있습니다.

Vue instance는 몇가지의 초기화 과정을 거칩니다. created, mounted 등의 생명주기 훅들은 this context가 Vue instance를 가리키도록 설정되고 나서 실행됩니다. 화살표 함수를 option property나 callback (created, watch … ) 에서 실행하지 말아야 합니다. 화살표 함수는 this를 가지고 있지 않기 때문에 this는 다른 변수들처럼 부모 스코프까지 렉시컬하게 조회되어 Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function 같은 에러를 발생시킬 수 있습니다.

저는 여기서 Vue가 this context를 어떻게 Vue instance에 바인딩하는지 궁금해졌습니다. Vue core 코드를 뜯어보았습니다.

image

initMixin을 따라가봅니다.

image

initState가 data를 초기화하는 부분같습니다. initState를 따라갑니다.

image

data가 있으면 initData를 호출합니다. 따라들어갑니다.

image

data가 함수타입이면 getData를 실행합니다. 따라들어갑니다.

image

드디어 찾고있던 마지막 종착지입니다. data.call(vm,vm)을 return합니다.

lifecycle hook의 경우에는 어떨까요? init.js에서 callHook(vm, 'created')를 따라갑니다.

image

invokeWithErrorHandling에 vm을 넘겨주고 있습니다.

image

똑같이 handler에게 context를 바인딩하면서 실행합니다.

예제를 만들어서 일반 함수와 화살표 함수의 동작원리를 비교해봤습니다. (Node.js 환경)

image

첫번째 예제에서는 this가 전부 전역 객체를 가리킵니다. ({})

image

두번째 예제에서는 생성자 함수로 객체를 만들어 바인딩해봤습니다. 화살표 함수의 경우 this context가 vm을 가리키지 못합니다.

image

call method의 첫번째 인자는 this, 두번째 인자부터는 함수의 매개변수로 값들이 전달됩니다. 화살표 함수도 vm을 잘 전달받습니다.

image

결론적으로, data에서 this를 사용하는 경우 화살표 함수를 쓰고 싶다면 vm을 인수로 넘겨줘야 하는데 굳이 이렇게까지 해서 화살표 함수를 쓰는 이점이 있을까? 라는 생각이 듭니다.

긴 글 읽어주셔서 감사합니다. 피드백은 언제나 환영입니다!


Written by@Donghoon Song
사람들의 꿈을 이어주는 코멘토에서 일하고 있습니다.

InstagramGitHubTwitterLinkedIn