var의 문제점을 이해하고 let/const를 언제 써야 하는지 배운다. 호이스팅과 TDZ(일시적 사각지대) 개념을 통해 자바스크립트 변수의 동작 원리를 파악한다.
변수란 무엇인가
변수(variable)는 값을 저장하는 이름 붙은 공간입니다. 자바스크립트에서 변수를 선언하는 방법은 세 가지입니다: var, let, const.
var name = "김철수"; // 구식 방법 (ES5)
let age = 25; // 재할당 가능 (ES6+)
const PI = 3.14159; // 재할당 불가 상수 (ES6+)
결론부터 말하면, 현대 자바스크립트에서는 var를 사용하지 않습니다. 기본적으로 const를 쓰고, 재할당이 필요할 때만 let을 씁니다.
var의 세 가지 문제점
1. 중복 선언 허용
var user = "Alice";
var user = "Bob"; // 에러 없이 덮어씀
console.log(user); // "Bob"
let user2 = "Alice";
let user2 = "Bob"; // SyntaxError: user2 이미 선언됨
2. 함수 스코프 (블록 스코프 없음)
// var는 블록({})을 무시함
if (true) {
var x = 10;
}
console.log(x); // 10 — 블록 밖에서도 접근됨!
// let은 블록 스코프
if (true) {
let y = 10;
}
console.log(y); // ReferenceError: y is not defined
3. 호이스팅으로 인한 혼란
// var는 선언 전에 접근하면 undefined 반환 (에러 없음)
console.log(score); // undefined (에러 아님!)
var score = 100;
// let은 선언 전 접근 시 에러 (TDZ)
console.log(count); // ReferenceError
let count = 0;
호이스팅(Hoisting) 이해하기
호이스팅은 자바스크립트 엔진이 코드를 실행하기 전 선언부를 스코프 최상단으로 끌어올리는 동작입니다. 실제 코드가 이동하는 것은 아니고, 엔진이 내부적으로 처리합니다.
// 개발자가 작성한 코드:
console.log(a); // undefined
var a = 5;
// 자바스크립트 엔진이 처리하는 방식 (개념적):
var a; // 선언만 끌어올림
console.log(a); // undefined
a = 5; // 할당은 그 자리에
함수 선언식도 호이스팅됩니다. 단, 함수 전체가 올라갑니다.
// 선언 전에 호출 가능
greet(); // "안녕하세요!" — 에러 없음
function greet() {
console.log("안녕하세요!");
}
TDZ — 일시적 사각지대(Temporal Dead Zone)
let과 const도 호이스팅은 됩니다. 하지만 선언 전 접근을 허용하지 않습니다. 선언 위치에 도달하기 전의 구간을 TDZ(Temporal Dead Zone)라고 합니다.
// 이 구간이 TDZ
// console.log(x); // ReferenceError: Cannot access before initialization
let x = 10; // TDZ 종료, 이제 접근 가능
console.log(x); // 10
TDZ는 버그를 일찍 잡아주는 보호 장치입니다. var의 "선언 전에 접근해도 undefined 반환"은 실수를 숨깁니다.
let — 재할당 가능한 변수
let count = 0;
count = 1; // 재할당 가능
count += 1; // count = 2
count++; // count = 3
let message; // 선언만 가능 (undefined)
message = "Hello";
// 블록 스코프
for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
// console.log(i); // ReferenceError — for문 밖에서 접근 불가
const — 재할당 불가 상수
const MAX_SIZE = 100;
// MAX_SIZE = 200; // TypeError: Assignment to constant variable
// 주의: 객체나 배열의 내부 값은 변경 가능
const user = { name: "Alice", age: 25 };
user.age = 26; // 가능 — 내부 프로퍼티 변경
// user = {}; // 불가 — 참조 자체 변경 불가
const fruits = ["apple", "banana"];
fruits.push("cherry"); // 가능
// fruits = []; // 불가
const는 "이 변수가 가리키는 대상을 바꾸지 않겠다"는 의미입니다. 객체 내부 변경은 허용합니다.
언제 let, 언제 const?
const 사용 (기본):
const API_URL = "https://api.example.com";
const user = { name: "Kim" };
const numbers = [1, 2, 3];
const handleClick = () => { ... };
let 사용 (재할당이 명확히 필요할 때):
let count = 0;
count++;
let isLoading = true;
isLoading = false;
for (let i = 0; i < 10; i++) { ... }
실무 규칙: 일단 const로 선언하고, "재할당이 필요하다"는 것이 명확해지면 그때 let으로 바꾸세요. 처음부터 let을 쓰는 것보다 이 습관이 더 안전한 코드를 만듭니다.
변수 명명 규칙
// 가능한 이름
let userName = "Kim"; // camelCase (권장)
let _private = true; // 언더스코어 시작 가능
let $element = null; // 달러 시작 가능
let user2 = "Lee"; // 숫자 포함 가능 (첫 글자 제외)
// 불가능한 이름
// let 2user = "Kim"; // 숫자로 시작 불가
// let user-name = ""; // 하이픈 불가
// let class = ""; // 예약어 불가
// 의미 있는 이름을 쓰세요
let a = 25; // 나쁨
let userAge = 25; // 좋음
let MAX_RETRY_COUNT = 3; // 상수는 SNAKE_CASE 관례
관련 검색어 · 자바스크립트 변수, let const 차이, var 문제점, 호이스팅이란, TDZ 일시적 사각지대, const 객체 변경