자바스크립트에서 this는 함수 호출 방식에 따라 다르게 바인딩된다. setTimeout 내에서 일반 함수를 사용하면 this가 객체를 가리킬 수 없다. 그러나 화살표 함수는 렉시컬 컨텍스트를 유지하므로, this가 객체를 가리키도록 만들 수 있다.
- 기존 문제: setTimeout 내에서 일반 함수로는 this를 예상대로 사용할 수 없다.
- 해결 방법: 화살표 함수를 사용해야만 this가 객체에 바인딩된다.
- 추가 실험: 중첩된 setTimeout에서도 화살표 함수로 설정된 this는 변하지 않는다.
반례 코드 (일반 함수 사용 시 this 문제)
const timer = {
title: "TIMER!",
timeout: function () {
console.log(this.title); // "TIMER!" 출력
setTimeout(function () {
console.log(this.title); // undefined 출력 (this는 글로벌 객체를 가리킴)
}, 1000);
}
}
timer.timeout();
위 코드에서 setTimeout 안의 일반 함수는 this를 객체가 아닌 글로벌 객체(브라우저에서는 window, Node.js에서는 global)에 바인딩하므로 this.title은 undefined가 된다.
해결 코드 (화살표 함수 사용 시 this 유지)
const timer = {
title: "TIMER!",
timeout: function () {
console.log(this.title); // "TIMER!" 출력
setTimeout(() => {
console.log(this.title); // "TIMER!" 출력 (this는 객체를 가리킴)
}, 1000);
}
}
timer.timeout();
화살표 함수를 사용하면 this가 외부 스코프를 그대로 유지하기 때문에, this.title은 "TIMER!"를 출력한다.
중첩된 상황에서도 this가 유지되는 경우
const timer = {
title: "TIMER!",
timeout: function () {
console.log(this.title); // "TIMER!" 출력
setTimeout(() => {
setTimeout(() => {
console.log(this.title); // 중첩되어도 "TIMER!" 출력
}, 1000);
}, 1000);
}
}
timer.timeout();
화살표 함수는 중첩되어 사용하더라도 this를 외부 스코프에 바인딩한 상태를 유지한다.
그렇가면 무조건적으로 화살표 함수로 설정하는게 좋은걸까?
객체 메서드 정의 시 화살표 함수의 문제
하지만 객체 메서드를 정의할 때 화살표 함수를 사용하면 this가 객체를 가리키지 않기 때문에 문제가 발생한다. 화살표 함수는 자신만의 this 바인딩을 갖지 않고 상위 스코프의 this를 그대로 사용하기 때문이다.
const obj = {
name: 'Jeon Byeongjun',
greet: () => {
console.log(`Hello, ${this.name}`); // undefined 출력 (this는 obj가 아닌 상위 스코프를 가리킴)
}
}
obj.greet(); // undefined 출력
화살표 함수로 객체 메서드를 정의하면, this가 상위 스코프에 바인딩되기 때문에 객체의 프로퍼티에 접근할 수 없다.
객체 메서드 정의 시 일반 함수 사용
객체 메서드를 정의할 때는 일반 함수 표현을 사용해야 this가 객체를 올바르게 가리키도록 할 수 있다.
const obj = {
name: 'Jeon Byeongjun',
greet: function() {
console.log(`Hello, ${this.name}`); // 'this'는 obj를 가리킴
}
}
obj.greet(); // Hello, Jeon Byeongjun 출력
일반 함수 표현을 사용하면 this는 객체를 가리키기 때문에, 객체의 프로퍼티에 제대로 접근할 수 있다.
결론
- 비동기 코드에서는 화살표 함수를 사용하여 this를 외부 스코프에 바인딩하는 것이 좋다.
- 객체 메서드 정의 시에는 일반 함수를 사용하여 this가 객체를 가리키도록 해야 한다.
자바에는 이런 부분까지는 고민은 안해도 됐는데… 참으로 심오한 언어다…
'코딩딩 > Javascript' 카테고리의 다른 글
Web (0) | 2023.08.28 |
---|