왜 밑의 두 문장처럼 호출되는지에 대해서 설명드리겠습니다.
일단 fighter.opponent.getFullname()을 호출하면 opponent 객체가 outer가 되고 이 outer안에 있는 getFullname이라는 객체의 this가 가르키는 객체는 다른 bind와 같은 지시해준 것이 없기 때문에 opponent를 가르키게 됩니다.
따라서 fighter.opponent.getFullname()이 호출 되면 opponent를 가르키는 this -> fullname인 Francis Ngannou가 호출이 됩니다. 여기서 중요한 것은 fighter.opponent.getFullname()는 호출의 주체가 명확한 메서드 입니다.
그다음 fighter.getName()를 호출하면 그냥 함수로서 호출한것이 아니라 outer를 분명하게 달고 호출을 하였기 때문에 마찬가지로 getName에서 가르키는 this는 fighter를 나타내게 됩니다. 여기서 중요한 것은 fighter.getName()도 호출의 주체가 명확한 메서드입니다.
세번째로 fighter.getFirstName()도 위와 같은 맥락으로 outer를 가지고 함수 호출이 일어났기 때문에 this는 fighter라는 outer를 가르키고 그 outer의 fullname의 앞글자인 John이 실행된다고 생각하겠지만 이번 문제의 함정입니다. 여기서는 화살표 함수로 나타냈기 때문에 화살표 함수 특성상 ThisBinding을 하지 않는 다는 것 입니다. 화살표 함수는 무조건 상위의 this를 바라보게 되어 있습니다. 그러기 때문에 fighter.getFirstName()의 this는 thisbinding을 하지 않았으니까 thisbinding을 마지막에 해줬던 'Ciryl Gane'을 가리키게 됩니다. 따라서 Ciryl이 됩니다. 여기서 중요한 것은 fighter.getFirstName()는 메서드로 호출이 되었지만 화살표 함수이기 때문에 ThisBinding이 되지 않았습니다.
마지막으로 this가 전역변수를 가르켜서 window에서 실행을 권장하게 만들었다는 이유에 관해서 설명하겠습니다. fighter.getLastName을 마지막으로 호출했는데 여기서 () 괄호를 사용하지 않은 호출부가 없이 호출을 했습니다. 그럼 fighter의 getLastName을 보면 스스로 선언하고 호출까지 하게 되었습니다. 따라서 바로 호출을한 독립성을 가진 함수로써 바로 즉시 실행 함수로써 일을 해서 getLastName을 그냥 call해서 getLastName이 가르키는 this는 전역변수를 나타내주기 때문에 Ciryl Gane를 가르켜 뒷부분인 Gane를 호출해 줍니다.
이 부분은 메서드의 내부라고 해도, 함수로서 호출한다면 this는 전역 객체를 의미합니다.
위와 같은 이유로 호출은 결국
Not Francis Ngannou VS John Jones
It is John Jones VS Ciryl Gane
로 나오게 됩니다.
여기서 궁금한 점은 그렇다면 fighter.getFirstName()의 위치를 fighter.opponent.getFirstName()으로 바꾸고 코드 순서도 바꾸면 어떻게 실행될까요?
정답은 바로 화살표 함수의 this는 전역객체를 가르킵니다.
'JavaScript' 카테고리의 다른 글
가장 많이 받은 선물 -JS (0) | 2024.08.20 |
---|---|
Math.min(Array)를 넣었더니 NaN이 나왔다 (0) | 2024.08.19 |
클로저 (Closure) (0) | 2024.08.16 |
(CallBack)콜백 함수의 콜백 지옥과 비동기 제어 (2) | 2024.08.14 |
(CallBack)콜백 함수 (0) | 2024.08.14 |