개발/JavaScript

[JavaScript] var, let, const의 차이점

xuwon 2024. 9. 5. 01:13

자바스크립트에서 var, let, const는 변수 선언을 위해 사용된다.
그렇다면 이 셋의 차이점은 무엇일까?

크게 스코프(Scope), 호이스팅(Hoisting), 중복 선언 이렇게 3가지 차이가 있다.

하나씩 뭔지 알아보자.

 

스코프

- 어떤 변수가 선언된 공간 또는 환경
- 어떤 변수의 스코프는 해당 변수가 접근될 수 있는 범위

1. 글로벌 스코프
- 함수나 블록 바깥에서 선언된 변수
- 어디에서든지 접근 가능

2. 함수 스코프 (= 지역 스코프)
- 함수 안쪽에서만 접근이 가능한 변수
- 블록 스코프를 무시

3. 블록 스코프 (ES6)
- 블록({}) 안에서만 접근 가능 (함수 포함)
- let, const에만 적용

 

호이스팅

자바스크립트 스코프 안에서 변수를 최상단에서 선언하는 것.
- var, let, const 변수는 모두 선언 시 호이스팅 적용

 

중복 선언

 같은 이름으로 변수를 다시 선언하는 것.
(변수 덮어쓰기를 방지하기 위해 도입된 안전 장치)

 

스코프, 호이스팅, 중복 선언에 대해 알아봤으면, 이제 var, let, const의 차이점을 살펴보자.

 

var


스코프

- 함수 스코프를 가진다. 즉, var로 선언된 변수는 함수 내에서만 유효하며, 함수 밖에서는 접근이 불가능.
- 함수 외부에서 선언된 경우 전역 스코프에서 유효!
- 또한 블록({}) 내에서 선언된 경우에도 블록 스코프를 무시하고 블록 밖에서도 접근할 수 있다.

호이스팅
- 선언과 초기화 모두 호이스팅! (초기값: undefined)
- 따라서 값 할당 전에 해당 변수를 참조하면 undefined가 출력됨.

중복 선언
- 가능

console.log(a); // undefined (호이스팅)
var a = 10;
console.log(a); // 10

if (true) {
    var b = 20;
}
console.log(b); // 20 (블록 스코프 무시)

이 코드를 보면,

a의 선언과 초기화는 호이스팅 되었으나, 1번째 줄에서는 값 할당 전이기에 undefined가 출력된다.
값 할당 후인 3번째 줄에서는 a가 10으로 정상적으로 출력된다. 

6번째 줄에서 변수 b는 블록 내에서 선언되었지만, 블록 밖에서 접근이 가능하다.

 

let


스코프

- 블록 스코프를 가진다. 즉, 블록({}) 내에서 선언된 변수는 그 블록 내에서만 유효하고, 블록 밖에서는 접근할 수 없다.

호이스팅
- 선언만 호이스팅
- 초기화는 호이스팅 되지 않는다. 따라서 초기화 이전에 접근 불가능. -> ReferenceError
- 스코프의 시작 지점부터 초기화 지점까지를 '일시적 사각지대 (TDZ)'라고 한다. (var는 일시적 사각지대가 없음.)

중복 선언
- 불가능

if (true) {
    let c = 30;
    console.log(c); // 30
}
// console.log(c); // ReferenceError (블록 스코프)

let d = 40;
// let d = 50; // SyntaxError (중복 선언 불가)

이 코드를 보면,

블록 내에서 선언된 c는 블록 내에서만 접근이 가능하다.
또한 d는 이미 선언됐으므로,  d라는 이름으로 중복 선언이 불가능하다.

 

const


스코프

- 블록 스코프를 가진다. 즉, 블록({}) 내에서 선언된 변수는 그 블록 내에서만 유효하고, 블록 밖에서는 접근할 수 없다.

호이스팅
- let과 동일
- 선언만 호이스팅

- 초기화는 호이스팅 되지 않는다. 따라서 초기화 이전에 접근 불가능. -> ReferenceError
스코프의 시작 지점부터 초기화 지점까지를 '일시적 사각지대 (TDZ)'라고 한다. 

중복 선언
- 불가능

재할당
- const로 선언된 변수는 초기화 이후 값을 변경할 수 없음. (객체의 속성이나 배열 요소는 변경 가능)

const e = 50;
// e = 60; // TypeError (재할당 불가)

const obj = { name: "Alice" };
obj.name = "Bob"; // 객체의 속성 변경 가능
console.log(obj.name); // Bob

 

정리하자면. . .

  호이스팅 초기값 스코프
var 선언, 초기화 모두 undefined 함수 스코프
let, const 선언만 (TDZ 존재) uninitialized 블록 스코프