정의 및 사용 방법
let 선언문(statement)은 글로벌 스코프 또는 블록({}) 스코프를 가지는 변수를 선언합니다.
같은 스코프에서는 재선언할 수 없지만, 재할당은 가능합니다.
- 재선언 불가
- 같은 스코프 내에서 동일한 식별자로 변수를 다시 선언할 수 없습니다.
- 재할당 가능
- 스코프와 상관없이 접근 가능한 스코프 내에서 동일한 식별자로 변수의 값을 바꿀 수 있습니다.
- 호이스팅(Hoisting) 발생
- 선언이 스코프의 최 상단 코드 위치로 끌어올려진 것처럼 동작합니다.
- 단, 변수가 선언된 위치보다 먼저 참조되면 에러를 발생시킵니다.
기억하세요!
var는 같은 스코프 내에서 재선언이 가능하지만, let은 불가합니다.
구문
let name1;
let name1 = value1;
let name1 = value1, name2 = value2;
let name1, name2 = value2;
let name1 = value1, name2, /* …, */ nameN = valueN;
nameN- 선언할 변수의 이름입니다. 이 이름은 자바스크립트에서 유효한 식별자이여야 합니다.
valueN-
옵션.
변수에 할당할 초깃값입니다. 이 값을 지정하지 않으면
undefined가 할당됩니다.
let의 주요 특징
let으로 선언된 변수의 특징에 대해 자세히 살펴보겠습니다.
초기화 상관 없음
let으로 선언된 변수에 초기화(변수 선언 시 값을 할당하는 것)는 상관 없습니다. 값을 할당해도 되고, 그렇지 않아도 됩니다. 값을 할당하지 않으면 참조 시 자바스크립트 엔진에서 자동으로 할당하는 초깃값인 undefined가 할당됩니다.
let a = 10;
console.log(a); // 출력: 10
let b;
console.log(b); // 출력: undefined
글로벌 스코프 또는 블록 스코프를 가지는 변수를 선언
- 블록 밖에서
let으로 선언된 변수는 코드 전체에서 유효한 글로벌(전역) 스코프를 가집니다. - 블록 내에서
let으로 선언된 변수는 해당 블록과 하위 블록 내에서 유효한 블록 스코프를 가집니다.
let으로 선언한 변수는 블록 밖에서 선언되었으면 글로벌에서 사용 가능(유효)하고, 블록 내에서 선언되었으면 해당 블록 내에서만 사용 가능(유효)합니다.
여기에서 블록의 의미에 대해 정확히 알고 있어야 let으로 선언된 변수의 스코프에 대해 정확히 파악할 수 있습니다.
블록({})의 의미
자바스크립트에서 블록은 중괄호 {}로 둘러싸인 코드 영역을 의미합니다.
다음은 블록의 일반적인 형태들입니다.
if () { // if 블록
// ...
} else { // else 블록
// ...
}
function exampleFn() { // 함수 블록
// ...
}
{ // 임의의 독립적인 블록 (일반적으로 잘 사용되지는 않음)
let temp = 10; // temp는 이 블록 내에서만 유효
}
for () { // for 블록
// ...
}
하지만, 중괄호가 없어도 문법적으로 중괄호가 있어야 하지만 생략된(if 또는 for 문 뒤의 단일 문장) 코드 영역 역시 개념적으로 블록에 해당지만, 실제 블록이 아니기 때문에 let으로 변수를 선언할 수 없습니다.
if (true) let a = 10; // Uncaught SyntaxError: Lexical declaration cannot appear in a single-statement context
let으로 선언한 변수의 글로벌 스코프 또는 블록 스코프
/* 글로벌(전역) 스코프 */
let globalVar = "글로벌 변수"; // 이 파일(또는 스크립트)의 최상위 블록 전체에서 유효함
function exampleFunction() {
/* 함수 블록 스코프 */
let functionVar = "함수 블록 변수"; // 함수 전체 블록에서 유효함
if (true) {
let innerBlockVar = "if 블록 변수";
console.log(functionVar); // 출력: "함수 블록 변수"
console.log(innerBlockVar); // 출력: "if 블록 변수"
}
// if 블록 스코프 외부이므로 참조 불가
// console.log(innerBlockVar); // ReferenceError (innerBlockVar is not defined)
}
if (true) {
let ifBlockVar = "if 블록 변수";
console.log(ifBlockVar); // 출력: "if 블록 변수"
}
exampleFunction();
console.log(globalVar); // 출력: "글로벌 변수"
// console.log(functionVar); // ReferenceError (functionVar is not defined)
// console.log(ifBlockVar); // ReferenceError (ifBlockVar is not defined)
재선언 불가
let으로 선언된 변수는 같은 스코프 내에서 재선언(Redeclaration)이 불가합니다.
같은 스코프 내에서 이미 let으로 선언된 변수를 동일한 식별자(변수 이름)로 변수를 다시 선언하면 오류가 발생합니다.
// 같은 스코프 내에서 let 동일한 식별자(변수 이름)로 변수를 다시 선언하면 오류가 발생
let exampleLet = 10;
let exampleLet = 100; // Uncaught SyntaxError: Identifier 'exampleLet' has already been declared
// 서로 다른 스코프 내에서 let 동일한 식별자(변수 이름)로 변수를 다시 선언은 가능
let exampleLet = 10;
console.log(exampleLet); // 출력: 10
if (true) {
let exampleLet = 100;
console.log(exampleLet); // 출력: 100
}
console.log(exampleLet); // 출력: 10
재할당 가능
let으로 선언된 변수의 재할당은 변수를 선언한 스코프와 상관없이 접근 가능한 스코프 내에서 동일한 식별자로 변수의 값을 바꿀 수 있습니다.
// 글로벌 스코프
let globalVar = "글로벌 변수";
console.log(globalVar); // "글로벌 변수"
// 재할당 가능
globalVar = "재할당된 글로벌 변수";
console.log(globalVar); // "재할당된 글로벌 변수"
if (true) {
// 블록 스코프
let blockVar = "블록 변수";
console.log(blockVar); // "블록 변수"
// 재할당 가능
blockVar = "재할당된 블록 변수";
console.log(blockVar); // "재할당된 블록 변수"
}
// 블록 밖에서는 참조 불가
// console.log(blockVar); // ReferenceError
모듈(Module) 환경에서 let
ES6 이후 import나 export 문을 사용하는 모듈 환경(.js 파일을 모듈로 불러오는 경우)에서는 let의 동작 방식에도 중요한 변화가 있습니다.
모듈은 파일을 단위로 독립적인 스코프를 가지기 때문에, 모듈 최상위 스코프에서 let으로 선언해도 더 이상 글로벌(전역) 객체[window(브라우저) 또는 global(Node.js)]에 등록되지 않습니다. 모듈 환경에서는 블록 밖에서 선언해도, 전역 객체에는 추가되지 않고 모듈 내부에서만 유효합니다.
- 모듈 내부에서 블록 밖에 선언한
let변수는 모듈 전체에서 접근 가능(유효)하지만, 모듈 외부에서는 접근할 수 없습니다. - 모듈 내부에서 블록 내에 선언된
let변수는 블록 스코프를 유지합니다.
// 모듈 내부에서 let 선언
let globalVar = "모듈 내부 글로벌 변수";
function exampleFunction() {
let functionVar = "함수 내 변수";
console.log(functionVar); // 출력: "함수 내 변수"
}
console.log(globalVar); // 출력: "모듈 내부 글로벌 변수"
// 모듈 외부에서 globalVar 접근 시
// 브라우저: window.globalVar → undefined
// Node.js: global.globalVar → undefined
TDZ(Temporal Dead Zone, 일시적 사각지대)
자바스크립트 인터프리터가 코드를 실행하기 전에 선언한 변수는 실제로 작성된 위치와 상관없이 스코프의 최 상단 코드 위치로 끌어올려진 것처럼 동작합니다. 이러한 동작을 호이스팅(Hoisting, 끌어 올리기)이라고 합니다.
다만, 실제 변수가 선언된 위치보다 먼저 참조되면 자바스크립트 엔진은 호이스팅 된 변수가 존재한다는 것을 체크할 수 있습니다. 이 때문에 변수가 선언되기 전에 접근해도 오류가 나지 않기 때문에 변수의 선언 순서가 엄격하게 적용되어야 하는 let에서는 에러를 발생시킵니다.
이렇게 선언된 변수의 스코프 시작점부터 실제 변수가 선언된 위치를 TDZ(Temporal Dead Zone, 일시적 사각지대)라고 합니다. TDZ는 let이나 const로 선언된 변수에만 적용됩니다.
// TDZ 영역 시작
// ↓
console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
// ↑
// TDZ 영역 종료
let myVar = 10;
호환성
| 문 |
데스크탑 Chrome
|
데스크탑데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
Node.js
|
|---|---|---|---|---|---|
let
|
49 | 14 | 44 | 10 | 6 |
명세서
| 명세서 사양 | |
|---|---|
let
|
ECMAScript® 2026 Language Specification #sec-variable-statement |