먼저하는 요약
1. object 내의 method에서 쓰는 this 는 그 method 를 가지고 있는 object를 뜻한다.
2. constructor 안에서 쓰는 this 는 새로 생성되는 object 를 뜻한다.
3. 이벤트리스너 안에서의 this 는 e.currentTarget(지금 이벤트가 동작하는 곳) 을 뜻한다.
* 화살표 함수 내부의 this 는 값을 변화시키지 않고 외부의 this 값을 그대로 재사용한다.
1. object 내의 method 에서 쓰는 this
object 내의 method에서 쓰는 this 는 그 method 를 가지고 있는 object를 뜻한다.
<script>
const obj = {
data: 'kim',
func: function () {
console.log(this);
},
};
obj.func(); // {data: 'kim', func: f}
// object 안의 method 에서 this 는 그 함수를 가지고 있는 object
</script>

우리가 global 함수를 만들면 사실 window 객체에 메서드를 만드는 것이므로
만약 globalFunc 라는 글로벌함수를 만든다면 우리는 이를 window.globalFunc() 라고 호출할 수 있다.
<script>
function globalFunc() {
console.log('글로벌 함수는 사실 window 객체의 메서드입니다..');
}
globalFunc();
window.globalFunc();
</script>

따라서 글로벌 함수에서 this 는 메서드의 주인인 window 객체를 반환한다.
<script>
console.log(this);
</script>

중첩된 객체의 내부 객체에서 this 는 무얼 가리킬까 ?
<script>
const obj = { // 외부 객체
data: { //내부객체
func: function () {
console.log(this);
},
},
};
obj.data.func(); // {func: f}
// 중첩 object 안의 method 에서 this 는 그 함수를 가지고 있는 object
// 따라서 obj 객체가 아닌 data 객체가 출력됨.
</script>

이것도 역시 this 가 해당 메소드를 가지고 있는 객체를 가리킨다.
따라서 obj 객체가 아닌 data 객체를 가리킨다.
2. constructor 안에서 쓰는 this
constructor 안에서 this 는 새로 생성되는 object (instance) 를 뜻한다.
<script>
function func() {
this.name = 'kim'; //여기서 this 는 새로생성되는 오브젝트(instance)
console.log(this);
}
const newobj = new func();
console.log(newobj);
// constructor 안에서 쓰면 새로 생성되는 오브젝트를 뜻함
</script>

3. 이벤트리스너 안에서 쓰는 this
이벤트리스너 안에서의 this 는 e.currentTarget (지금 이벤트가 동작하는 곳) 을 뜻한다.
<script>
document.getElementById('button').addEventListener('click', function (e) {
console.log(this); // 이벤트리스너 안에서의 this 는 e.currentTarget ( 지금 이벤트가 동작하는 곳)
console.log(e.currentTarget); // <button id = 'button'>button</button>
});
// 이벤트리스너 안에서의 this 는 e.currentTarget(지금 이벤트가 동작하는 곳) 을 뜻함
</script>

이런 경우는 어떨까?
case1. 이벤트 리스너 콜백함수 내부 forEach 함수의 콜백함수 안에서 this
<script>
document.getElementById('button').addEventListener('click', function (e) {
const array1 = [1, 2, 3];
array1.forEach(function (a) {
console.log(this); // window => 이벤트리스너의 콜백함수안에서 forEach의 콜백함수는 전역함수이기때문
});
});
</script>

비록 이벤트리스너 내부이지만 forEach 메서드는 window 전역객체의 메서드 이므로 forEach 의 콜백함수는 전역함수이다. 따라서 this 는 window 를 가리킨다.
case2. 객체 내에서 콜백함수를 쓸때의 this
<script>
const obj = {
names: ['kim', 'lee', 'park'],
func: function () {
console.log(this); //---1 얘는 obj 객체를 출력
obj.names.forEach(function () {
console.log(this); //---2 얘는 window 출력
});
},
};
obj.func(); // forEach 의 콜백함수는 그냥 일반함수이기때문에 this 는 window 가 나옴
</script>

1 번의 this 는 메서드의 주인인 obj 객체를 출력한다.
2 번의 this 는 forEach 의 콜백함수 내에서 this를 출력 했으므로 case1 과 같은 이유로 window 를 출력한다.
화살표 함수 내부의 this
arrow function 에서의 this 는 내부의 this 값을 변화시키지 않고 외부의 this 값을 그대로 재사용한다.
<script>
const obj = {
data: {
func: () => {
console.log(this);
},
},
};
obj.data.func(); //window
// arrow function 을 쓰면 this 는 window
</script>

이런 화살표함수의 특성을 이용하면 bind, call,apply 등의 this 바인딩을 대체할수 있다.
<script>
const obj = {
names: ['kim', 'lee', 'park'],
func: function () {
console.log(this); // 얘는 obj4를 출력
obj.names.forEach(() => {
console.log(this); // 얘도 obj4 출력
});
},
};
obj.func(); // 화살표 함수는 내부의 this 값을 변화시키지 않고 외부의 this 값을 그대로 재사용 한다.
</script>

참고로 use strict 를 적용한 strict 모드에서는 일반 함수의 this 가 undefined 를 출력한다.
<script>
'use strict';
console.log(this); // window
function funct() {
console.log(this);
}
funct(); // undefined
// strict mode 에서는 그냥쓰면 this 가 window 일반함수내에서 쓰면 undefined
</script>

'javascript' 카테고리의 다른 글
| 콜백 함수, promise, async await 그리고 동기와 비동기 (0) | 2022.03.30 |
|---|---|
| array, object 콘솔에서 출력할 때 신기한 점 - console lazy evaluation (0) | 2022.03.25 |
| js sort 함수로 정렬해버리기 (0) | 2022.03.24 |
| for문 삼대장 - for ...of , for ...in, forEach (0) | 2022.03.10 |
| fileReader 로 client 브라우저에서 파일 다루기 (0) | 2022.03.04 |
댓글