자바스크립트 퀴즈북 리마인드 Day 9: this는 호출한 쪽이.
this 바인딩을 정의 위치가 아니라 호출 형태, 메서드 분리, arrow function, bind 기준으로 읽는 방법을 코드 리뷰 관점에서 정리합니다.
오늘의 질문: “객체 안에 있던 메서드를 콜백으로 넘기면 this도 같이 따라갈까?”const user = {
name: "Jing",
sayName() {
return this.name;
},
};
const say = user.sayName;
console.log(user.sayName());
console.log(say());첫 번째는 "Jing"입니다. 두 번째는 strict mode 기준으로 TypeError가 나거나, 환경에 따라 전역 객체를 보면서 undefined처럼 보일 수 있습니다. 같은 함수처럼 보여도 호출 형태가 달라졌기 때문입니다.
this는 “함수가 어디에 적혀 있었는가”보다 함수가 호출될 때 왼쪽에 어떤 객체가 남아 있는가를 먼저 봅니다.
객체 안에 함수를 넣으면 this가 그 객체에 영구히 묶인다고 생각하기 쉽습니다. 하지만 자바스크립트에서 함수는 값입니다. 값을 변수에 담거나 콜백으로 넘기는 순간, 원래 객체와의 연결은 자동으로 따라가지 않습니다.
const profile = {
name: "Jing",
print() {
console.log(this.name);
},
};
setTimeout(profile.print, 0); // 의도한 this가 아니다이 코드는 “나중에 profile.print()를 호출한다”가 아닙니다. profile.print라는 함수 값을 꺼내서 timer에게 넘긴 것입니다. timer가 나중에 그 함수를 어떻게 호출하는지는 profile 객체와 별개입니다.
| 호출 모양 | this 판단 | 리뷰 질문 |
|---|---|---|
obj.method() | this는 보통 obj | 왼쪽 객체가 호출 순간에 남아 있나? |
const fn = obj.method; fn() | 메서드 연결이 사라짐 | 값만 분리한 뒤 호출하지 않았나? |
fn.call(obj) / bind(obj) | 명시적으로 this를 지정하거나 고정 | 의도한 객체를 정말 고정해야 하나? |
() => this.method() | arrow가 자기 this를 만들지 않고 바깥 값을 캡처 | 바깥 this가 안전한 위치인가? |
this 문제는 대부분 문법 암기보다 “함수 값이 이동했는가?”를 추적하면 잡힙니다.
프론트엔드 코드에서 자주 보는 실수는 클래스나 객체 메서드를 이벤트 핸들러로 바로 넘기는 경우입니다.
class Counter {
count = 0;
increment() {
this.count += 1;
}
}
const counter = new Counter();
button.addEventListener("click", counter.increment);increment는 Counter 안에 정의되어 있지만, 이벤트 리스너로 넘어갈 때는 함수 값만 전달됩니다. 그래서 this가 counter라고 보장되지 않습니다.
의도가 “항상 counter를 증가시킨다”라면 고정해야 합니다.
button.addEventListener("click", counter.increment.bind(counter));또는 클래스 필드 arrow function처럼 처음부터 바깥 인스턴스를 캡처하는 방식도 있습니다.
class Counter {
count = 0;
increment = () => {
this.count += 1;
};
}둘 중 무엇이 낫다는 규칙보다, 리뷰에서는 “이 함수가 어디로 전달되고, 호출자가 누구인가?”를 먼저 봐야 합니다.
arrow function은 자기만의 this를 만들지 않습니다. 이 말은 메서드로 쓰면 오히려 의도가 틀어질 수 있다는 뜻이기도 합니다.
const user = {
name: "Jing",
sayName: () => this.name,
};여기서 this는 user가 아닙니다. 객체 리터럴이 새 this를 만들어 주지 않기 때문입니다. arrow function은 “호출 지점의 this를 무시하고 바깥 this를 쓰겠다”는 선택에 가깝습니다.
그래서 리뷰 기준은 단순합니다.
객체의 동작을 메서드로 표현해야 하면 일반 메서드가 자연스럽다.
콜백으로 넘겨도 인스턴스/상위 스코프를 보존해야 하면 arrow나 bind를 고려한다.
this를 쓰지 않아도 되면 아예 인자를 명시적으로 받는 함수가 더 읽기 쉽다.
메서드를 변수에 담거나 props/callback으로 넘기면서 this 연결이 끊기지 않았는가?
이벤트 핸들러, timer, Promise callback 안에서 this가 실제 호출자를 기준으로 안전한가?
bind가 렌더마다 새 함수를 만들며 불필요한 리렌더나 removeEventListener 실패를 만들지 않는가?
arrow function을 객체 메서드처럼 쓰면서 this가 객체라고 착각하지 않았는가?
this 대신 명시적 인자나 closure가 더 단순한 설계는 아닌가?
this는 특별한 마법이라기보다 호출 규칙입니다. 코드 리뷰에서는 “이 함수가 정의된 자리”보다 “나중에 누가 어떤 모양으로 부르는지”를 따라가면 훨씬 덜 헷갈립니다.
"const say = user.sayName;\nsay();"Post Q&A
자바스크립트 퀴즈북 리마인드 Day 9: this는 호출한 쪽이 정한다 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
콜 스택, 태스크 큐, 마이크로태스크 큐를 기준으로 Promise와 setTimeout 실행 순서를 코드 리뷰 관점에서 정리합니다.