this라는 의미는 그냥 당장 지금 호출된 함수라던가 그 내부 변수를 가르킬것 같지만
직접 코딩을 하다보면 this가 생각과 다른것을 가르키고 있을때가있다.
그래서 this에 대해 정확히 정리하고 넘어가기로 한다.
this는 어떤 방식으로 호출하느냐에 따라 가리키는 값이 달라지는데,
this는 실행 컨텍스트가 생성될때 결정된다 = 즉 ,함수가 호출(실행) 될때 결정
1 전역 공간에서의 this
전역 공간에서의 this는 전역객체 window 를 가리킨다.
2 메서드로 호출할때 그 내부에서의 this
메서드 내부에서의 this에는 호출한 주체(함수명 앞의 객체)에 대한 정보 가 담긴다.
점 표기법이든 대괄호 표기 법이든, 어떤 함수를 호출할때
그 함수이름 앞에 객체가 명시되어있는 경우는 메서드로 호출한 것이고,
그렇지 않은 모든 경우에는 함수로 호출한 것이다.
↓ 함수와 메서드의 차이
위의 예시를 보면 outer의 this에는 outer가 찍혔지만,
inner의 this에는 window객체가 찍혔다. 이유가 무었일까?
obj.outer() 과 inner()의 차이다. 메서드와 함수로 불리는 부분에 차이가 있는 것이다.
하지만 이 this를 우회해서 inner의 this도 변경해 줄 수 있다.
2 - 1 메서드 내부에서의 this를 우회하기
1 ) this를 변수에 할당해서 사용하기
' 보통 this를 self라는 변수에 할당해서 우회한다고 한다 '
위와 같은 예제에 const self = this; 라고 설정하고
inner의 this부분에 self를 변경하였다.
outer 내에서 this를 self라는 변수에 할당해 주었기 때문에
inner의 this는 outer의 this와 같은 값을 가리킨다.
2 ) arrow function 사용하기
ES6의 화살표 함수는 실행 컨텍스트를 생성할 때 this자체가 바인딩이 되지 않고,상위 스코프의 this를 활용하기 때문이다
3 콜백함수 호출 시 내부에서의 this
콜백함수의 제어권을 가지는 함수가 콜백함수에서의 this를 무엇으로 할지를 결정하며,
특별히 정의하지 않은 경우에는 기본적으로 함수와 마찬가지로 전역객체를 바라본다.
위의 예제를 보면 ,
obj.setEmail을 보면 인자를 받아 this.email로 설정하는데, 이것을 이용해
callback이라는 함수를 사용하여 cd 인자로 obj.setEmail 함수를 호출하고 email 인자로는 이메일 주소를 넘겨주었다.
그렇다면, obj의 setEmail의 email이 변경될것이라고 생각하는데
생각과 달리 obj의 email은 변하지 않았다.
오히려 전역객체인 window의 email이 원하던 값으로 변경되었다.
이유는 무엇일까?
callback이라는 함수에 console로 this를 출력해보면,
window ,즉 전역 객체가 출력되는데 때문에 위에서 생각했던 결과가 나오지 않는것이다.
전역객체가 this인 이유는, this를 정의할때 this는 어떤 방식으로 호출하느냐에 따라 가리키는 값이 달라진다고 했는데,
객체의 메서드를 콜백함수로 사용하면, 메서드가 함수로써 호출되어 this가 달라진다는 점을 알아두어야한다.
즉, 위의 callback함수에서 obj.setEmail을 호출했을때,
위와 같은 과정을 거치는데, 이때의 setEmail은 obj 내부에 있는 메서드가 아니라 함수로써 호출되어
제어권을 가져가기 때문에 이때의 this는 obj가 아닌 전역객체 window를 가르키고 있고, 위와같은 결과가 나오는 것이다.
그래서 this를 바인딩 하는 방법을 따로 정리해 두었다.
↓ 참고
4 생성자함수 내부에서의 this
어떤 함수가 생성자 함수로써 호출된 경우 내부에서의 this는 새로 만들어진 그 함수 자신이 this가 된다
✓ 참고
[ 코어 자바스크립트 - 저자 정재남 ]
'JavaScript' 카테고리의 다른 글
[JavaScript] 콜백함수의 this와 콜백지옥 (0) | 2020.11.16 |
---|---|
[JavaScript] 명시적으로 this를 바인딩하는 방법 (0) | 2020.11.12 |
[Javascript] 실행 컨텍스트와 호이스팅, 스코프체인 (0) | 2020.11.03 |
[Javascript] 실행 컨텍스트와 환경정보 (0) | 2020.11.02 |
[ Javascript 모듈화 ] AMD, CommonJs, ES6의 모듈 (0) | 2020.09.12 |