스코프와 호이스팅
JavaScript의 가장 헷갈리는 두 가지 개념을 완벽히 이해하기
스코프란
var vs let/const
스코프 체인
호이스팅
CHAPTER 01
스코프 (Scope)
변수가 사용 가능한 범위예요. 어디서 변수를 접근할 수 있는지 결정합니다.
정의
CONCEPT
학교 비유:
전역 = 학교 전체 (모두 접근)
함수 = 특정 교실 (그 반만)
블록 = 개인 책상 (나만)
전역 = 학교 전체 (모두 접근)
함수 = 특정 교실 (그 반만)
블록 = 개인 책상 (나만)
var (함수 범위) — 문제 있음 ❌
function test() {
var x = 10;
if (true) {
var x = 20; // 같은 x!
}
console.log(x); // 20 (if 블록 밖인데!)
}
test();
var x = 10;
if (true) {
var x = 20; // 같은 x!
}
console.log(x); // 20 (if 블록 밖인데!)
}
test();
❌ 문제: if 블록 안의 x가 함수 전체의 x에 영향을 줘요. 예측 불가능!
let/const (블록 범위) — 안전 ✅
function test() {
let x = 10;
if (true) {
let x = 20; // 다른 x!
}
console.log(x); // 10 (원래대로)
}
test();
let x = 10;
if (true) {
let x = 20; // 다른 x!
}
console.log(x); // 10 (원래대로)
}
test();
✅ 안전: if 블록 내의 x는 if 블록 안에서만 존재. 바깥의 x는 영향 없음!
스코프 체인 (Scope Chain)
HIERARCHY
안쪽 스코프는 바깥쪽 변수를 볼 수 있어요:
✅ 블록 스코프 → 함수 스코프 → 전역 스코프 (위로 검색)
❌ 함수 스코프 → 블록 스코프 (아래로는 불가)
✅ 블록 스코프 → 함수 스코프 → 전역 스코프 (위로 검색)
❌ 함수 스코프 → 블록 스코프 (아래로는 불가)
let global = "전역";
function myFunc() {
let funcVar = "함수";
if (true) {
let blockVar = "블록";
console.log(global); // ✅ OK
console.log(funcVar); // ✅ OK
console.log(blockVar); // ✅ OK
}
console.log(blockVar); // ❌ ReferenceError!
}
function myFunc() {
let funcVar = "함수";
if (true) {
let blockVar = "블록";
console.log(global); // ✅ OK
console.log(funcVar); // ✅ OK
console.log(blockVar); // ✅ OK
}
console.log(blockVar); // ❌ ReferenceError!
}
💡 핵심: 안쪽 스코프는 바깥쪽 변수를 볼 수 있지만, 바깥쪽은 안쪽 변수를 볼 수 없어요!
CHAPTER 02
호이스팅 (Hoisting)
JavaScript가 코드를 실행하기 전에 미리 선언을 끌어올리는 현상입니다.
var 호이스팅 — 버그 유발 ❌
당신의 코드
console.log(x);
var x = 10;
var x = 10;
JavaScript가 해석
var x; ← 끌어올려짐!
console.log(x); // undefined (에러 아님!)
x = 10;
console.log(x); // undefined (에러 아님!)
x = 10;
❌ 문제: 에러가 안 나서 버그를 찾기 어려워요!
let/const 호이스팅 — 즉시 에러 ✅
당신의 코드
console.log(x);
let x = 10;
let x = 10;
JavaScript 실행
❌ ReferenceError: x is not defined
(즉시 버그 발견!)
(즉시 버그 발견!)
✅ 안전: 에러가 바로 나타나서 쉽게 찾을 수 있어요!
복잡한 예제: 호이스팅 문제
var scope = '전역';
function fnc() {
// var scope; ← 여기서 선언됨 (호이스팅)
console.log(scope); // undefined (전역 아님!)
var scope = 'local';
console.log(scope); // 'local'
}
fnc();
function fnc() {
// var scope; ← 여기서 선언됨 (호이스팅)
console.log(scope); // undefined (전역 아님!)
var scope = 'local';
console.log(scope); // 'local'
}
fnc();
⚠️ 복잡한 이유: 함수 내에 var scope가 있으면, JavaScript가 함수 전체에서 그 scope를 사용해요. 그래서 첫 번째 console.log에서 '전역'이 아니라 undefined가 나옵니다!
❌ 결론: var는 예측 불가능한 버그를 만들어요. 절대 쓰면 안 됩니다!
SUMMARY
스코프와 호이스팅 정리
var vs let vs const 최종 비교
COMPARISON
| 항목 | var | let | const |
|---|---|---|---|
| 스코프 | 함수 | 블록 ✅ | 블록 ✅ |
| 호이스팅 | undefined ❌ | ReferenceError ✅ | ReferenceError ✅ |
| 중복선언 | 가능 ❌ | 불가 ✅ | 불가 ✅ |
| 재할당 | 가능 | 가능 ✅ | 불가 ✅ |
| 추천 | 금지 ❌❌❌ | 권장 ✅ | 권장 ✅ |
💚 기억해야 할 3가지:
1️⃣ 기본으로
2️⃣ 값이 변해야 하면
3️⃣ 절대로
1️⃣ 기본으로
const 사용2️⃣ 값이 변해야 하면
let으로 변경3️⃣ 절대로
var 쓰지 마기