- Published on
JavaScript의 var, let, const 비교
- Authors
- Name
- 신주용
변수 선언을 위한 키워드 var, let, const
자바스크립트에서는 변수 선언에 사용할 수 있는 키워드가 3가지 있습니다. 바로 var
, let
, const
입니다. 이 중 var
는 기존에 있던 키워드이고 let
, const
는 ES6에 새롭게 추가된 키워드입니다. 세 키워드 모두 변수 선언에 사용되지만, 범위(scope)와 동작이 약간씩 다릅니다. 어떤 점에서 차이를 보이는지 알아보겠습니다12.
변수 범위 (Scope)
var
는 함수 내에서 선언될 떄는 함수 범위, 함수 밖에서 선언될 떄는 전역 범위로 동작. 그러므로 함수 안의 if문과 같이 한 단계 더 안에서 var
변수를 선언한다고 생각해 봅시다. var
변수는 if문 밖이더라도 동일한 함수 안이라면 변수에 접근이 가능합니다.
function a() {
{
var b = 1;
}
console.log(b); // 가능. 1 출력
}
반면, let
, const
는 블록 범위입니다. 같은 함수 안이더라도 내부 블록에서 선언했다면 해당 블록 밖에서는 접근이 불가합니다.
function a() {
{
let b = 1;
}
// console.log(b); // ReferenceError: Can't find variable: b
}
초기값
var
, let
은 선언 시 초기화를 안 한다면 기본적으로 undefined
로 초기화됩니다.
> var a;
< undefined
> let b;
< undefined
const
를 사용할 때는 무조건 선언 시 초기값을 할당해줘야 합니다.
> const a;
< SyntaxError: Unexpected token ';'. const declared variable 'a' must have an initializer.
호이스팅 (Hoisting)
var
는 함수나 전역 범위의 제일 위로 호이스팅 됩니다. 다만, 변수의 선언부만 호이스팅 되고 초기값은 자동으로 undefined
가 들어가게 됩니다. 그러므로 이렇게 사용할 때는 동작에 주의가 필요합니다. 예상치 못한 값이 들어가 있을 수 있기 때문입니다.
function a() {
// var b = undefined; // 실제 코드 아님. 내부적으로는 호이스팅 되어 동작. undefined로 초기화.
console.log(b); // 호이스팅 되었으므로 가능. undefined 출력.
var b = 1;
console.log(b); // 1
}
let
, const
도 호이스팅이 되기는 하지만, var
와는 달리 호이스팅 때는 자동으로 초기화되지 않습니다. 그러므로 이 때 변수 사용을 시도하면 ReferenceError
가 발생합니다.
function a() {
// let b; // 실제 코드 아님. 내부적으로는 호이스팅 되어 이렇게 선언된 것처럼 동작. 초기화는 안 됨.
console.log(b); // ReferenceError: Cannot access uninitialized variable.
// 호이스팅 되었으므로 a라는 변수가 있는건 알지만 초기화 안되어 에러 발생.
let b = 1;
}
변수에 값 재할당
var
는 재선언, 재할당이 가능합니다. 특히 재선언이 가능한 점이 특이한데, 호이스팅 되어 함수 범위의 최상단에 선언이 이미 된 것처럼 동작하기 때문에 가능합니다.
function a() {
// var b = undefined; // 실제 코드 아님. 함수 범위 최상단으로 호이스팅 되어 동작. undefined로 초기화.
{
var b = 1; // b를 1로 초기화. b = 1; 과 동일한 동작.
var b = 2; // b에 2를 재선언. b = 2; 와 동일.
}
var b = b + 1; // b를 최초 선언한 부분은 내부 블록 안이라 자바 같은 언어에서는 오류가 나겠지만,
// JS에서는 호이스팅되어 함수 최상단에 선언된 것처럼 동작하므로 문제 없음.
console.log(b); // 3
}
let
은 재할당은 가능하지만, 동일 범위 내에서 재선언은 불가합니다.
function a() {
{
// let b; // 실제 코드 아님. 블록 범위 최상단으로 호이스팅 되어 동작. 초기화 없음.
let b = 1; // b를 1로 초기화. b = 1; 과 동일한 동작.
// let b = 2; // SyntaxError: Cannot declare a let variable twice: 'b'.
// 동일 범위에서 재선언 불가.
b = 2; // 재할당은 가능.
console.log(b); // 2
}
let c = b + 1; // ReferenceError: Can't find variable: b
// b를 초기화한 부분은 내부 블록이므로 여기서는 알 수 없는 변수.
}
const
는 재선언, 재할당이 모두 불가능합니다.
function a() {
{
// const b; // 실제 코드 아님. 블록 범위 최상단으로 호이스팅 되어 동작. 초기화 없음.
const b = 1; // b를 1로 초기화. b = 1; 과 동일한 동작.
// const b = 2; // SyntaxError: Cannot declare a let variable twice: 'b'.
// 동일 범위에서 재선언 불가.
// b = 2; // TypeError: Attempted to assign to readonly property.
// 재할당도 불가.
}
const c = b + 1; // ReferenceError: Can't find variable: b
// b를 초기화한 부분은 내부 블록이므로 여기서는 알 수 없는 변수.
}
통합 테스트
위 내용을 종합적으로 테스트 해보는 코드와 실제 실행 결과는 다음과 같습니다.
function a() {
// var m = undefined; // hoisted. not real code, just for explanation.
// var m of ln 7 and ln 9. declared and initialised.
console.log("before block: ", m); // before block: undefined
{
var m = "a: 1";
var m = "a: 2"; // able to redeclare
console.log("in block: redeclare: ", m); // in block: redeclare "a: 2"
m = "a: 3"; // able to reassign
console.log("in block: reassign: ", m); // in block: reassign: "a: 3"
}
console.log("after block: ", m); // after block: "a: 3"
// because var is function-scope
}
a();
console.log("out of fn a: ", m); // ReferenceError: Can't find variable: m
function b() {
{
// let n; // hoisted. not real code, just for explanation.
// var m of ln 7 and ln 9. declared but not initialised.
// console.log("before block: ", n); // ReferenceError: Can't find variable: n
let n = "b: 1";
// let n = "b: 2"; // SyntaxError: Cannot declare a let variable twice: 'n'.
console.log("in block: redeclare: ", n); // in block: redeclare: "b: 1"
n = "b: 3"; // able to reassign
console.log("in block: reassign: ", n); // in block: reassign: "b: 3"
}
// console.log("after block:", n); // ReferenceError: Can't find variable: n
// because var is block-scope
}
b();
// console.log("out of b:", n); // ReferenceError: Can't find variable: n
function c() {
{
// const o; // hoisted. not real code, just for explanation.
// var m of ln 7 and ln 9. declared but not initialised.
// console.log("before block:", o); // ReferenceError: Can't find variable: o
const o = "c: 1";
// const o = "c: 2"; // SyntaxError: Cannot declare a const variable twice: 'o'.
console.log("in block: redeclare: ", o); // in block: redeclare: "c: 1"
// o = "c: 3"; // TypeError: Attempted to assign to readonly property.
// console.log("in block: reassign: ", o);
}
// console.log("after block:", o); // ReferenceError: Can't find variable: o
// because const is block-scope
}
c();
// console.log("out of c:", o); // ReferenceError: Can't find variable: o
Prerequisites: 이 글에서 언급되었으나 깊게 설명하지 않은 내용입니다.
- 변수 호이스팅 (Hoisting)
- TDZ(Temporal Dead Zone)
Footnotes
Sarah Chima Atuonwo. "Var, Let, Const의 차이점은?" freecodecamp.org. https://www.freecodecamp.org/korean/news/var-let-constyi-caijeomeun/ (accessed Sep. 07, 2023). ↩
인파. "📚 var / let / const 차이점 정리 (변수 호이스팅)." Inpa Dev 👨💻💻. https://inpa.tistory.com/entry/JS-📚-var-let-const-차이점-변수-호이스팅 (accessed Sep. 07, 2023). ↩