자바스크립트에서 사용하는 this라는 키워드는 4가지 뜻을 가지고 있다.
1)window :
먼저 window이다. 전역에서 this키워드를 출력해보면 콘솔에 window가 출력되는 것을 알 수 있다.
이 키워드를 또 함수안에서 사용해도 this는 window라는 값을 출력한다.
그런데, 만약에 여기에 use strict모드를 사용하면, 함수 안에서의 this는 undefinded를 출력하게 될 것이다.
use strict모드는 문법적으로 조금 더 엄격한 모드를 말한다.
<script>
'use strict'
console.log(this)
function 함수() {
console.log(this);
}
함수()
</script>
2)object :
두 번째 this의 뜻은 그 자체의 오브젝트를 뜻한다. 아래와 같이 하나의 오브젝트 안에, 함수를 넣어놓고, 그 함수 안에 this를 출력한 경우 이 this는 자신이 속해 있는 객체를 출력한다.
<script>
console.log(this)
var 오브젝트 = {
data : 'Kim',
함수 : function(){
console.log('안녕')
}
}
오브젝트.data;
오브젝트.함수()
</script>
조금 더 풀어서 말하면 오브젝트 내 함수안에서 쓰면 그 함수를 가지고 있는 오브젝트를 뜻한다.
만약, 아래와 같이 객체 안에 또 다른 객체를 만들어서, 그 객체 안에서 this를 출력하는 함수를 만들면 어떻게 될까?
<script>
//this의 첫번째 뜻은 window이다.
console.log(this)
var 오브젝트 = {
data : {
함수 : function() {
console.log(this);
}
}
}
오브젝트.data;
오브젝트.data.함수()
</script>
data라는 객체를 출력한다. this는 자신을 포함하고 있는 가장 가까운 객체를 출력한다.
그런데, 만약에 신 문법인 화살표함수를 사용하는 경우에는 함수 바깥에 있는 그대로 가져다 사용한다. 결과적으로 아래와 같이 작성한 경우에 window라는 값을 출력한다.
var 오브젝트 = {
data : {
함수 : () => {
console.log(this);
}
}
}
지금까지 1번 2번을 설명했는데, 사실 똑같은 의미이다. 전역에서 this를 출력하나, 객체 안에서 this를 출력하나 가장 가까운 공간 안에서의 객체를 출력하는 것이다.
전역에서 this를 선언했을 때의 경우에는 , 우리가 여러 함수나 변수를 전역공간에 만들었을 때 window에 보관된다는 사실을 알 수 있다.
이 window를 전역변수 보관소라고 부를 수 있다. 우리가 함수를 전역에 만들었으면, window라는 객체 안에서 함수를 만들었다고 생각하면된다.
전역에서 this를 출력하면 그냥 window가 나옵니다 라고 말하면 98%만 맞은 것이다. 자신을 포함하고 있는 객체를 출력하는데 그게 window여서 그것을 출력한다고 말하면 더 정확하다.
3)기계(constructor) 안에서 쓰면 새로 생성되는 오브젝트를 뜻함 :
this의 세번째 의미는, constructor를 생성할 때, 사용된다. 하나의 함수안에서 this를 사용하면, 그것의 constructor를 생성한다. 이 constructor는 반복해서 객체를 찍어내주는 기계라고 생각하면 된다.
this를 통해서 constructor를 생성했다면, 이것을 어떻게 뽑아낼까? 새로운 변수를 만들고 거기에 new 기계()라는 키워드를 생성하면 된다. 그러면 기계로부터 새로운 객체값, 그러니까 인스턴스를 생성할 수 있게 된다.
<script>
function 기계 () {
this.이름 = 'Kim';//이 this는 새로 생성되는 오브젝트(instance)를 뜻한다.
}
var 오브젝트 = new 기계(); //이렇게 출력하면 {이름 : 'Kim'}이라는 객체 값이 출력된다.
</script>
4)이벤트리스너 :
이벤트 리스너 안에서 this를 사용하면, 이것은 e.currentTarget이라는 뜻으로 사용된다. e.currentTarget를 사용하려면 본래, 파라미터로 e를 넘겨줘야 한다.
<script>
document.getElementById('버튼').addEventListener('click',
function(){
this; //e.currentTarget이라는 뜻으로 사용될 수 있다.
})
</script>
그런데, 특이 케이스가 있다.
case1. 이벤트리스너 안에서 콜백함수를 쓴다면 this는 ? :
함수 안에 함수를 넣은 것을 콜백함수라고 부른다. 파라미터 안에 들어간 함수를 콜백함수라고 부르는데, 함수를 순차적으로 사용하고 싶을 때 사용한다고 생각하면 된다.
그런데, 지금 이 콜백함수 안에서 this를 출력하면 어떻게 될까?
document.getElementById('버튼').addEventListener('click', function(e){
var 어레이 = [1,2,3];
어레이.forEach(function(){
console.log(this)
});
});
이렇게 출력하면 window가 나온다. 우리는 항상 this의 의미를 구분하려고 할 때, 이 함수가 쓰인 위치가 어딘지를 확인해야 한다. 이 함수가 쓰인 위치에 따라서 this의 값은 변하게 되어있다. 지금 상황에서 이 this는 그냥 일반함수 안에서 쓰였다고 생각하면 된다. 그렇기 때문에, 그냥 window를 출력하는 것이다. 현재의 함수는 엄밀히 말하면 전역함수라고 생각하면 된다.
case 2. 오브젝트 안에서 콜백함수를 쓴다면 this는?
이 상황에서 this를 출력하면 어떤 값이 나올까?
var 오브젝트 = {
이름들 : ['김', '이', '박'];
함수 : function(){
오브젝트.이름들.forEach(function(){
console.log(this)
});
}
}
이 값은 window를 출력한다. 왜 window가 나오는 것일까? 콜백에 들어가 있는 함수를 보면 이 함수는 근본이 없는 함수이다. 그냥 일반 함수이다. 이 친구를 포함하고 있는 객체인 window를 출력한다. 만약 함수라는 키값 안에서 this를 다시 출력하면 어떻게 될까? 오브젝트를 출력하게 될 것이다.
this의 바로 위에 있는 함수가 무엇인지를 생각해보면, this의 의미를 알 수 있다.
case 3.arrow function 안에서의 this는? :
arrow function의 특징이 있다면, 내부의 this값을 변화시키지 않는다. this값을 그냥 위에 있는 this값을 그대로 가져다 쓰게 된다. 아래의 경우 this값은 오브젝트가 된다.
var 오브젝트 = {
이름들 : ['김', '이', '박'];
함수 : function(){
오브젝트.이름들.forEach(() => {
console.log(this)
});
}
}
이게 에로우 함수의 장점이라고 할 수 있다. this값을 변화시키지 않고, 그대로 사용하려고 할 때 에러우 함수를 사용하면 된다.
애플코딩이라는 강의를 듣고 메모한 글입니다. 굉장히 좋은 강의라고 느끼면서 노트를 해나가는 중입니다. 자바스크립트의 심화된 버전을 공부하고 싶은 분들에게 추천합니다.
'Javascript' 카테고리의 다른 글
[자바스크립트] tagged literals 사용방법 (0) | 2021.10.04 |
---|---|
[자바스크립트] var, let, const 3가지 변수에 대한 정리 (0) | 2021.09.28 |
[자바스크립트] 자바스크립트의 동작원리 (stack, queue, event loop) (0) | 2021.09.20 |
[Javascript] 참조형과 원시형의 차이(reference vs primitive values) (0) | 2021.07.15 |
[javascript] 문서 위치 변경하는 법 (assign메서드) (0) | 2021.06.21 |