JavaScript의 변수 선언: var, let, const 차이점
JavaScript에서는 변수를 선언할 때 var, let, const 세 가지 키워드를 사용할 수 있다.각각의 키워드는 스코프, 재할당 가능 여부, 그리고 호이스팅 동작 방식에 차이가 있어 적절한 상황에서 선택하는 것이 중요하다.
1. var
var 는 JavaScript의 초기부터 사용된 변수 선언 방식이다. 하지만 몇 가지 특이한 동작 방식 때문에 현재는 잘 사용되지 않으며, let 이나 const 가 더 많이 사용된다.
- 스코프: 함수 스코프(function-scoped)
- var 로 선언된 변수는 함수 내에서만 유효하며, 블록( { } ) 내부에서 선언해도 함수 전체에 접근이 가능하다 - 재할당 가능 여부: 가능
- 호이스팅: 선언과 동시에 초기화되며, 선언 위치와 관계없이 상단으로 끌어올려진다.
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10
}
example();
2. let
let 은 ES6에서 도입된 변수 선언 방식으로, 블록 스코프를 가진다
- 스코프: 블록 스코프(block-scoped)
- let 은 { } 블록 내에서만 유효하여, 블록 외부에서는 접근할 수 없다 - 재할당 가능 여부: 가능
- 호이스팅: let 도 호이스팅되지만, 초기화되지 않고 일시적 사각지대(TDZ)에 놓인다. 이로 인해 선언 전에 변수에 접근하면 ReferenceError 가 발생한다
function example() {
if (true) {
let y = 20;
console.log(y); // 20
}
console.log(y); // ReferenceError
}
example();
3. const
const 는 변경할 수 없는 변수를 선언할 때 사용된다.
- 스코프: 블록 스코프(block-scoped)
- 재할당 가능 여부: 불가능. 하지만 객체나 배열 같은 참조 자료형은 내부 값을 수정할 수 있다.
- 호이스팅: let 과 동일하게 호이스팅되지만 초기화되지 않으며, TDZ가 적용된다.
const z = 30;
z = 40; // TypeError: Assinged to constant variable
const obj = { name: "Alice" }
obj.name = "Bob"; // 객체의 속성 수정은 가능
키워드 | 스코프 | 재할당 | 호이스팅 |
var | 함수 스코프 | 가능 | 선언 + 초기화됨 |
let | 블록 스코프 | 가능 | 선언만, TDZ 있음 |
const | 블록 스코프 | 불가능 | 선언만, TDZ 있음 |
var 가 잘 사용되지 않는 이유
1. 함수 스코프 (블록 스코프가 아님)
var 는 블록 스코프가 아니라 함수 스코프를 따르기 때문에, 블록 내에서 선언해도 해당 함수 전체에서 접근이 가능해서, 블록 외부에서도 변수가 유효하게 된다. 이로 인해 예기치 않은 변수 값이 사용되는 문제가 발생할 수 있다.
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10 - 블록 외부에서도 접근 가능
}
2. 호이스팅과 초기화
var 로 선언된 변수는 호이스팅 시 선언과 동시에 undefined 로 초기화된다. 그래서 선언 위치와 관계없이 함수 상단으로 끌어올려져 사용할 수 있지만, 변수가 예기치 못한 값 (undefined) 으로 초기화되는 문제가 발생할 수 있다.
console.log(x); // undefined - 선언 전에도 접근 가능
var x = 10;
let 과 const 는 선언 전 접근 시 에러가 발생하기 때문에 이런 문제를 피할 수 있다.
3. 전역 객체에 자동으로 추가됨
var 로 선언된 전역 변수는 전역 객체 (window 나 global 객체)에 자동으로 추가된다. 이로 인해 변수 충돌이 발생할 가능성이 높아진다.
var globalVar = "global";
console.log(window.globalVar); // global
4. 반복문에서 클로저 문제
반복문 안에서 var 를 사용하면 클로저 문제가 발생할 수 있다. var 는 블록 스코프가 없기 때문에, 반복문이 종료된 후에도 마지막 반복 값이 남아 있어 의도와 다른 동작을 한다
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// 1초 후 3, 3, 3 출력 - 반복 종료 후 i가 3으로 남음
let 을 사용하면 블록 스코프 덕분에 각 반복마다 독립적인 변수를 가지므로 이 문제를 해결할 수 있다.
'JavaScript' 카테고리의 다른 글
[JavaScript] 정규식 (0) | 2024.11.16 |
---|---|
[JavaScript] this (2) | 2024.11.10 |
[JavaScript] == (느슨한 비교) 와 === (엄격한 비교) (0) | 2024.11.09 |
[JavaScript] Truthy와 Falsy 값 (2) | 2024.11.09 |
[JavaScript] every() 와 some() (1) | 2024.11.09 |