let user = {
name: "a",
normalFunc: function() {
setTimeout(function(){
console.log("일반 함수 호출 구조 : " + this.name);
}, 500);
},
arrowFunc: function() {
setTimeout(() => {
console.log("화살표 함수가 정의되어있는 곳 : " + this.name);
}, 1000);
},
};
user.normalFunc();
user.arrowFunc();
코드 핵심 - setTimeout과 this의 관계
이 코드는 일반 함수와 화살표 함수의 this
바인딩 차이를 setTimeout
컨텍스트에서 보여줌.
1. 일반 함수의 this 동작
normalFunc: function() {
setTimeout(function(){ // 일반 함수 사용
console.log("일반 함수 호출 구조 : " + this.name);
}, 500);
}
- 결과: "일반 함수 호출 구조 : undefined"
- 이유:
normalFunc
는user
객체의 메서드setTimeout
은 콜백 함수를 내부적으로 다른 실행 컨텍스트에서 실행함- 일반 함수는 자신만의
this
를 생성하는데,setTimeout
에서 실행될 때는 전역 객체(브라우저에서는 window) 또는 undefined를 가리킴 - 따라서
this.name
은undefined
가 됨 - 중요:
setTimeout
이 콜백 함수를 실행할 때this
바인딩을 "마음대로" 바꿔버림
2. 화살표 함수의 this 동작
arrowFunc: function() {
setTimeout(() => { // 화살표 함수 사용
console.log("화살표 함수가 정의되어있는 곳 : " + this.name);
}, 1000);
}
- 결과: "화살표 함수가 정의되어있는 곳 : a"
- 이유:
arrowFunc
도user
객체의 메서드- 화살표 함수는 매우 중요한 특성이 있음: 자신만의
this
를 생성하지 않음 - 화살표 함수는 "렉시컬 스코프(Lexical Scope)"의
this
를 그대로 상속받음 - 렉시컬 스코프란 "화살표 함수가 정의된 위치의 환경"을 의미함
arrowFunc
메서드 내에서 화살표 함수가 정의되었으므로, 화살표 함수 내this
는arrowFunc
의this
(즉,user
객체)를 그대로 물려받음- 따라서 화살표 함수 안에서
this.name
은user.name
과 동일한 "a"를 정확히 가져옴
핵심 정리 - this의 동작 방식
- 일반 함수의 this:
- 호출 방식에 따라
this
가 동적으로 결정됨 obj.method()
형태로 호출하면this
는obj
를 가리킴- 하지만
setTimeout
같은 환경에서는this
바인딩이 달라짐 - 콜백 함수로 전달된 일반 함수 내부의
this
는 전역 객체 또는 undefined를 가리킴
- 호출 방식에 따라
- 화살표 함수의 this:
- 선언된 위치(렉시컬 스코프)에 따라
this
가 정적으로 결정됨 - 화살표 함수는
this
를 "태어난 곳"(정의된 위치)에서 물려받음 setTimeout
에서도 원래 환경의this
를 그대로 유지함- 따라서 콜백 함수로 전달되어도 외부 스코프의
this
를 기억함
- 선언된 위치(렉시컬 스코프)에 따라
실무 응용 방법
- 콜백에서 상위 스코프 this 접근 방법:
// 방법 1: 화살표 함수 사용 (권장) setTimeout(() => { console.log(this.name); }, 1000); // 방법 2: 변수에 this 저장 const self = this; setTimeout(function(){ console.log(self.name); }, 1000); // 방법 3: bind 메서드 사용 setTimeout(function(){ console.log(this.name); }.bind(this), 1000);
- 언제 무엇을 사용할지:
- 콜백에서 상위 스코프의
this
가 필요하면 → 화살표 함수 - 콜백 내에서 자체적인
this
바인딩이 필요하면 → 일반 함수 - 메서드 정의 시에는
this
바인딩이 필요하므로 → 일반 함수 사용 권장
- 콜백에서 상위 스코프의
이 코드는 자바스크립트에서 가장 많이 혼동되는 개념인 this
의 동작을 명확하게 보여주는 훌륭한 예제입니다.
이미지 속 예제 코드 다시 보기:
let user = {
name: "a",
normalFunc: function() {
setTimeout(function(){
console.log("일반 함수 호출 구조 : " + this.name);
}, 500);
},
arrowFunc: function() {
setTimeout(() => {
console.log("화살표 함수가 정의되어있는 곳 : " + this.name);
}, 1000);
},
};
user.normalFunc();
user.arrowFunc();
이 코드의 "핵심" setTimeout
안에서 this
가 어떻게 동작하는지 보여주는 것! 특히 일반 함수 ( function
) 와 화살표 함수 ( =>
) 를 비교해서 this
의 차이점을 강조하고 있어.
1. normalFunc
: "일반 함수" 에서 setTimeout
사용했을 때 ⏰
normalFunc: function() {
setTimeout(function(){ // 👈 일반 함수 (function 키워드)
console.log("일반 함수 호출 구조 : " + this.name);
}, 500);
},
normalFunc
는user
객체의 "메서드" 야.function
키워드로 만들어진 "일반 함수" 메서드이지.setTimeout(function(){ ... }, 500);
:setTimeout
은 "일정 시간 (500ms, 0.5초) 후에 "특정 함수" 를 실행해줘!" 라고 예약하는 기능이야. 여기서는setTimeout
에 "익명 함수 (이름 없는 함수)" 를 "콜백 함수" 로 전달했어. 콜백 함수는 "나중에 실행될 함수" 라고 생각하면 돼.console.log("일반 함수 호출 구조 : " + this.name);
: 이 부분이 핵심!setTimeout
에 전달된 "콜백 함수 (익명 함수)" 안에서this.name
을 출력하려고 하고 있어. 여기서this
가 뭘 가리키느냐가 중요한 거야!
결과: user.normalFunc()
를 실행하면, 약 0.5초 후에 콘솔에 "일반 함수 호출 구조 : undefined" 라고 출력될 거야.
왜 undefined
가 나올까? 🤔
setTimeout
이 "콜백 함수" 를 실행할 때,this
값을 "제대로 설정해주지 않기 때문" 이야. 정확히 말하면,setTimeout
이 콜백 함수를 "전역 객체 (window)" 또는 "undefined" 환경에서 실행시켜 버려.user
객체의normalFunc
메서드 안에서setTimeout
을 호출했지만,setTimeout
의 콜백 함수 안의this
는user
객체를 "가리키지 않게 되는" 거야.- 주석
//this : 본인을 호출한 객체를 참조
는 "일반적인 객체 메서드" 의this
동작 방식을 설명한 것인데,setTimeout
콜백 함수에서는 "예외" 가 적용되는 거야.setTimeout
은this
를 멋대로 바꿔버리는 "나쁜 녀석" 이라고 생각해도 괜찮아! 😅
2. arrowFunc
: "화살표 함수" 에서 setTimeout
사용했을 때 🏹
arrowFunc: function() {
setTimeout(() => { // 👈 화살표 함수 (=>)
console.log("화살표 함수가 정의되어있는 곳 : " + this.name);
}, 1000);
},
arrowFunc
도user
객체의 "메서드" 야. 하지만setTimeout
에 전달하는 콜백 함수를 "화살표 함수 (=>
)" 로 사용했다는 점이normalFunc
와 달라.setTimeout(() => { ... }, 1000);
:setTimeout
에 콜백 함수로 "화살표 함수 (익명 화살표 함수)" 를 전달했어.console.log("화살표 함수가 정의되어있는 곳 : " + this.name);
: 핵심! 이번에는setTimeout
콜백 함수가 "화살표 함수" 이기 때문에,this
동작 방식이 달라져!
결과: user.arrowFunc()
를 실행하면, 약 1초 후에 콘솔에 "화살표 함수가 정의되어있는 곳 : a" 라고 출력될 거야.
왜 "a"
가 제대로 나올까? ✨
- 화살표 함수는
this
를 "특별하게" 처리하기 때문 이야! 화살표 함수는this
를 "자신이 정의된 곳의 스코프에서 "상속" 받아와." 이걸 "렉시컬 스코프 (Lexical Scope)" 라고 불러. 말이 좀 어렵지만, 쉽게 말하면 "화살표 함수가 "태어난 곳" (정의된 곳) 의 "환경" 을 그대로 가져온다" 는 뜻이야. arrowFunc
메서드 안에서 화살표 함수가 정의되었지?arrowFunc
메서드 안에서this
는 "당연히"user
객체를 가리켜. (객체 메서드니까!) 화살표 함수는 이arrowFunc
메서드의this
(즉,user
객체) 를 "그대로 물려받아서" 사용하는 거야. 그래서 화살표 함수 안에서this.name
은user.name
과 똑같은 값인"a"
를 제대로 가져올 수 있는 거지.- 주석
//arrowFunc : this가 user라는 객체
와////화살표 함수가 정의된 위치 : arrowFunc()의 this
가 바로 이 점을 설명하고 있는 거야. 화살표 함수 안의this
는arrowFunc
의this
(user
객체) 와 "똑같다" 는 것을 강조하는 거지.
핵심 정리! 🔑
setTimeout
콜백 함수에서this
가 헷갈리는 이유:setTimeout
은 콜백 함수의this
를 "마음대로" 바꿔버리기 때문! (전역 객체 또는 undefined 로)- 일반 함수 (
function
) 콜백:setTimeout
안에서this
가user
객체를 "가리키지 않아서"this.name
이undefined
가 됨. - 화살표 함수 (
=>
) 콜백: 화살표 함수는this
를 "렉시컬 스코프에서 상속" 받기 때문에,setTimeout
안에서도arrowFunc
의this
(user
객체) 를 "그대로 유지" 해서this.name
이"a"
를 제대로 출력함.
'JS' 카테고리의 다른 글
[시험대비JS] 드롭다운 (통과) (0) | 2025.04.17 |
---|---|
Javascript DOM 이벤트 정리 (0) | 2025.04.14 |
[JS] 자바스크립트 기초 개념 정리 최종 (0) | 2025.04.09 |
[JS] JavaScript 개념 요약 (반복문부터) (0) | 2025.04.09 |
[JS] JavaScript 개념 요약 (0) | 2025.04.09 |