일반 함수에서 this가 실행환경 즉 execution context에 의해 좌우되는 반면 arrow 함수의 this는 lexical environment 즉 함수가 선언된 환경에 좌우된다. 말이 쓸데없이 복잡한데 정리하면 arrow 함수는 자체적으로 this를 바인딩하지 않고 외부의 this를 사용한다.
위 코드에서 eat는 일반 함수이므로 execution context를 따르고 cat을 통해서 호출하므로 this는 cat이다.
다음으로 cat.sleep에 대해 살펴보자. sleep은 arrow 함수여서 외부(cat)의 lexical 환경을 가져오는데 cat은 전역에 선언된 객체이므로 cat의 lexical environment는 전역(window)이다. (객체 리터럴은 새로운 스코프를 만들지 않는다.) 따라서 cat.sleep에서 this는 window 객체이다.
마지막으로 info 내부에 있는 getLen을 살펴보자. 이 녀석도 arrow 함수이므로 외부의 this를 물려받는다. 여기서는 info라는 함수 내부에 있으므로 info의 this를 가져간다. info는 cat을 통해서 불려지므로 getLen의 this는 cat이 된다.
만약 아래와 같이 변경한다면?
let toGlobal = cat.info;
toGlobal();
이제 toGobal이 전역이고 toGlobal 내부의 getLen은 외부를 따라가므로 이때의 this는 전역 객체가 된다.