자바스크립트에서 나에게 어려운 파트가 뭐냐고 물어본다면 바로 this
를 꼽을 것이다.
지속적으로 공부하고있지만, 아직도 다 이해가 되지는 않고, 이런 것이구나 하는 대략적인 정보를 습득한 느낌이다.
그래도 블로그를 정리하면서 한번 정리해 보면 더 이해가 되지 않을까 싶어서 정리를 해본다.
주로 코드종의 this강의를 참고했다.(링크 하단)
MDN에서 this
요약
대부분의 경우,
this
의 값은 함수를 호출하는 방법에 의해 결정된다. 실행하는 동안의 할당에 의해 설정될수 없고, 함수가 호출될 때 마다 다를 수 있다.
기본적인 this
값
브라우저에서 콘솔을 열어서 this
를 입력해보면 window
가 나온다.
이로써 기본적으로 this
는 window
임을 알 수 있다.
윈도우에서 호출하면 window
객체를 반환하는 것이다.
호출하는 방법에 의해 결정된다는 뜻 예시
const someone = {
name: 'chan',
whoAmI: function() {
console.log(this);
}
};
const myWhoAmI = someone.whoAmI;
/* 1번 */
someone.whoAmI(); // {name: 'chan', whoAmI: f}
/* 2번 */
myWhoAmI(); // Window {}
1번 예시에서 this
를 호출한 것은 someone
객체이다. 그러므로 this
는 someone
이다.
2번 예시도 1번 예시와 같아 보이는데 Window객체를 반환한 이유는 1번 예시는 whoAmI
를 호출한 직접적인 객체는 someone
이지만 2번은 JavaScript
를 실행하는 기본적인 환경은 브라우저이기 때문에 global에서 호출한 myWhoAmI()
에서 this
는 원도우 객체가 나오는 것이다.
그렇다면 someone.whoAmI
를 addEventListener
버튼으로 실행하면 어떻게 될까?
html 파일
...
<body>
<Button id='btn'></Button>
<script src='main.js'></script>
</body>
JS 파일
const someone = {
name: 'chan',
whoAmI: function() {
console.log(this);
}
};
const btn = document.getElementById('btn');
btn.addEventListener('click', someone.whoAmI);
위와 같이 만든 버튼을 만들고, 버튼을 클릭하면 어떻게 될까?
버튼을 클릭해서 this
를 보면 아래와 같은 결과가 출력된다.
<button id='btn'>...</button>
그 이유는 메서드whoAmI
를 직접 호출한 것은 button
이기 때문이다.
MDN에서는 대부분의 경우라는 말을 사용했다. 그러면 예외가 존재한다는 말이다.
여기서의 예외는 bind
, call
, apply
이다.
여기서 bind
를 살펴보면 this
를 호출할때와 상관 없이 this
를 묶는다.
const someone = {
name: 'chan',
whoAmI: function() {
console.log(this);
}
};
const myWhoAmI = someone.whoAmI;
// 여기에서 myWhoAmI에서 this를 someone으로 바인딩 해보겠다.
const bindedWhoAmI = myWhoAmI.bind(someone);
const btn = document.getElementById('btn');
btn.addEventListenr('click', bindedWhoAmI);
위의 버튼을 클릭해보면 this
가 아래같이 바뀐다.
{name: 'chan', whoAmI: f}
화살표 함수에서는 클로저처럼 this
가 바인딩된다.
화살표 함수는 함수를 선언할 때
this
에 바인딩할 객체가 정적으로 결정된다. 동적으로 결정되는 일반 함수와 달리 화살표 함수의this
는 언제나 상위 스코프의this
를 가리킨다. 이를 *Lexical this** 라 한다.
엄격모드에서는 this
가 다르게 동작한다.
엄격모드를 적용하지 않으면 this
는 무조건 값을 반환했었다. (프로토타입 체이닝에 의해서인 것으로 생각한다.)
하지만 엄격모드에서의 함수에서는 함수내에서 window
객체를 this
를 통해 참조할 수 없다.