자바스크립트 퀴즈북 리마인드 Day 7: 클로저 버그와 오래된.
클로저가 값 복사가 아니라 렉시컬 환경 참조라는 점을 stale closure, 루프 콜백, React 이벤트 리뷰 관점에서 정리합니다.
예상 읽기 시간: 12분
오늘의 질문: “콜백 안에서 읽는 값은 함수가 만들어진 곳을 볼까, 호출된 곳을 볼까?”
const label = "global";
function makeLogger() {
const label = "local";
return function log() {
console.log(label);
};
}
const log = makeLogger();
log();출력은 local입니다. 함수는 호출된 위치가 아니라 생성된 위치의 렉시컬 환경을 기억합니다. 이게 스코프 체인과 클로저의 핵심입니다.
“나중에 실행됐으니까 그때 주변 값을 보겠지”라고 생각하면 비동기 콜백, 이벤트 핸들러, React effect에서 자주 틀립니다. 자바스크립트 함수는 실행 시점마다 아무 스코프나 다시 고르지 않습니다. 함수 객체가 만들어질 때 바깥 환경 참조가 함께 붙고, 실행 때는 그 참조를 따라 이름을 찾습니다.
둘 다 선언은 스코프의 시작 지점에서 준비됩니다. 차이는 “읽을 수 있는가”입니다.
| 선언 | 선언 전 읽기 | 스코프 | 리뷰 포인트 |
|---|---|---|---|
var | undefined | 함수 | 루프·콜백에서 같은 바인딩을 공유하기 쉽다 |
let | TDZ 에러 | 블록 | 선언 순서가 의도를 더 잘 드러낸다 |
const | TDZ 에러 | 블록 | 재할당 금지이지 객체 불변은 아니다 |
console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError
let b = 1;var가 “안전”한 게 아닙니다. 오히려 버그를 조용히 숨길 수 있습니다. 리뷰할 때는 undefined가 의도된 값인지, 선언 순서가 읽는 사람에게 명확한지 확인해야 합니다.
이벤트 핸들러가 오래된 상태를 닫아두고 있지 않은가?
루프 안 콜백이 같은 var 바인딩을 공유하지 않는가?
const 객체를 내부에서 바꾸면서 불변처럼 말하고 있지 않은가?
선언보다 사용이 먼저 나와서 TDZ나 undefined 흐름을 만들지 않는가?
스코프 체인은 문법 지식보다 “이 함수가 어떤 값을 기억하고 실행되는지”를 추적하는 도구에 가깝습니다.
Post Q&A
자바스크립트 퀴즈북 리마인드 Day 6: 스코프 체인과 호이스팅 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
스코프 체인, 클로저, var/let/const 호이스팅 차이를 콜백·상태 버그 리뷰 관점에서 짧게 정리합니다.