유튜브 ZeroCho 인간 JS 엔진 되기 영상을 보고 정리한 내용입니다.
this 를 개발자도구에서 콘솔 찍어보면 window 가 나옵니다. 기본적으로 브라우저에서 this 는 window 라고 생각할 수 있습니다.
대신 'use strict' 모드를 적용하면 undefined 가 나오는 점을 기억해둡시다.
중요한 것은 this가 바뀌는 시점입니다. 객체 안에 name 이란 키값을 가진 프로퍼티가 있을 때, 다른 함수 프로퍼티에서 this.name 을 호출하면 window.name 이 아닌 해당 객체의 name 을 반환합니다.
그렇다고 this 가 항상 obj 를 가르키진 않습니다. 아래 같은 경우에는 undefined가 나옵니다. this 는 함수가 호출될 때 결정됩니다.
함수를 호출할 때 앞에 객체가 오고, 그 함수 안에 this가 있을 때 해당 객체를 this가 가르킵니다. 위 객체의 함수는 아래 코드를 축약한 것인데,
아래 처럼 화살표 함수를 사용하면 this는 window 를 가르켜 undefined 가 됩니다. 화살표 함수 여부도 this 를 결정하는 데 큰 역할을 합니다.
this 가 달라지는 것들을 조금 더 살펴보면,
아래처럼 생성자 함수로 객체를 생성하면 this는 객체 자기 자신이 됩니다.
또 bind (새로운 함수 만들기, 호출까지 안함), apply(새롭게 만들어서 호출까지), call (apply와 비슷) 을 사용하면 this를 지정할 수 있습니다.
기본적으로 this 는 window 인데 바뀌는 경우는, 앞에 객체를 붙여서 호출하는 경우와 New 붙여서 호출하는 경우, bind, apply, call 로 this 를 직접적으로 바꿔주는 경우가 있습니다. this 는 코드를 쓰는 순간 정해지기 보다는 함수를 호출할 때 정해집니다.
화살표 함수의 this 는 무조건 window, 전역을 가르키는 것이 아니라 부모의 스코프를 가르킵니다. 아래 객체안의 this는 화살표 함수의 부모 스코프는 widow 입니다. (스코프 확인은 선언을 보면 됩니다.)
조금 더 복잡하게 들어가면, 아래와 같은 코드가 있을 때 inner 의 스코프체인은 inner - sayName - anonymous 입니다. 함수에서 다른 변수에 접근할 수 있는지 여부를 보기 위해 스코프체인을 확인합니다.
이때 obj.sayName() 을 하면 sayName의 this 는 obj 를 가르켜 name의 밸류값을 가져오지만 inner 안의 this 는 window 를 가르켜 빈칸이 나옵니다. sayName 은 호출할 때 앞에 obj 를 불렀지만 inner 는 함수 호출할 때 this 를 바꾸어주는 동작을 하지 않았습니다. 만약 inner 가 화살표 함수가 된다면 둘다 값이 찍힙니다. 화살표 함수는 부모함수의 this 를 그대로 가져옵니다. (sayName 이 화살표 함수라면 obj 가 아닌 부모요소를 가르킴)
부모함수의 this 를 보기 위해서는 그 함수가 호출될 때를 보아야 합니다. 선언만 보고는 this 를 판단할 수 없습니다. 머릿속으로 아래처럼 호출스택을 그릴 수 있어야 합니다. (선언말고 쌓이는 호출만 보는, 이때 this 를 꼬리표처럼 붙여주면 편함 )
이때 inner 가 화살표 함수가 아니라면 inner 의 this 는 window 가 됩니다.