본문 바로가기
  • 구름빵의 개발 블로그
Front-End/JavaScript,TypeScript

[JavaScript] 변수 var, let, const

by 은빛구름빵 2025. 9. 4.

개요

JavaScript를 사용하면서 변수를 지정할 때 따로 자료형을 지정해주지 않는다. 그렇기에 JavaScript에서는 변수를 선언할 때 변수 이름과 키워드를 통해 선언해줄 수 있다.

 

0. 모든 키워드 공통

var, let, const 모두 적용되는 공통적인 특징으로 Hoisting이 이루어진다는 특징이 있다.

Hoisting이란, 코드가 빌드되는 과정에서 함수, 변수 선언 및 import 문을 먼저 선언하도록 순서를 변경되는 작업을 의미한다.

// 작성 코드
console.log( name );
var name = "Lee";

// 실제 실행되는 과정
var name;
console.log( name );
name = "Lee";

위 코드를 보면 실제 코드를 작성할 때 선언을 사용보다 뒤에서 해도 코드가 에러 없이 작동하는 것을 알 수 있다.

실행해보면 위 코드는 콘솔에 undefined라는 값을 보여주게 된다. 

에러가 아닌 undefined라는 값을 보여주는 이유는 var 변수의 경우 선언과 동시에 undefined로 초기화를 하게 되어 있다.

let과 const의 경우는 선언은 되지만 초기화가 되지 않으므로 값이 없다는 에러가 나오게 된다.

 

여기서, TDZ( Temporay Dead Zone )이라는 개념이 같이 언급된다.

TDZ란, 변수가 선언되고 해당 변수에 값이 대입되기 전까지의 범위를 의미한다.

// 작성 코드

console.log( track );
...
let track = 24;

// 실제 작동 과정
let track;
console.log( track );
...
track = 24;

위 예제를 보면 let track; 으로 선언된 곳부터 track=24; 라고 값을 대입한 곳까지 저 사이는 track이라는 변수가 존재하지만 값은 없는 상태가 된다.

이러한 범위를 TDZ라고 한다.

1. var

제일 먼저 var를 이용한 변수 선언이다. 

var number = 10;

var name = "Lee";

var isActive = true;

위처럼 var + 변수명 형태를 통해 변수를 선언해줄 수 있다.

 

var 키워드의 특징은 제일 먼저 함수 스코프를 갖는다는 특징이 있다.

특이한 특징인데, 일반적으로 변수를 선언하는 우리는 블록 스코프를 기본으로 알고 있다.

function play( number ) {
	var result;
    if( number % 2 == 0 ) {
    	var track = 10;
        result = track + number;
    }
    else {
    	var track = 15;
        result = track - number;
    }
    console.log( track );
	return result;
}

위 예제에서 보면 track 변수들은 if문 안에서 선언되었다. 따라서 console.log()에서 track을 출력할 때는 에러가 나는게 정상이라고 생각한다.

하지만 var는 '함수 스코프'를 갖기 때문에 함수 내에서 선언되면 함수 안이라면 어디서든 읽을 수 있다는 특징이 있다.

여기서 모든 변수 선언을 let으로 만든다면 당연하게도 console.log()에서 에러가 난다.

 

다음 특징은 동일한 이름으로 변수를 재선언할 수 있다는 점이다.

같은 이름의 변수의 값을 변경하는 것이 아닌 재선언함으로써 값을 변경할 수 있다는 특징이 있다.

var number = 10;
var number = 20;

console.log( number );	// 20

 

원래 같았으면 2번 줄에서 에러가 났을 것이다. '같은 이름으로 된 변수가 중복으로 선언되었다'는 에러가 났을텐데 위 예제는 에러가 나지 않는다. number라는 변수 값이 아래 값으로 덮어 씌워진 것이다.

따라서, 재정의가 된다는 특징이 있다는 것을 알 수 있다.

이건 마냥 장점이라고 할 수 없는게 개발 과정에서 실수로 같은 이름의 변수를 만들었다면 원하는 대로 로직이 작동하지 않는 문제가 발생할 수도 있다.

 

2. let

let 키워드는 var와 동일하게 변수를 선언하는 키워드지만 var과 다른 점은 우리가 흔히 알고 있는 블록 스코프를 갖는다는 점이다.

위 play 함수와 같은 경우에서, var를 모두 let으로 바꾼다면 아래 console.log()에서 해당 변수에 값이 없다고 에러가 날 것이다.

function play( number ){
	let result;
    if( number % 2 == 0 ) {
    	let track = 10;
        result = track + number;
    }
    else {
    	let track = 20;
        result = track - number;
    }
    console.log( track );
    return result;
}

result는 if-else 조건문 밖에서 선언되었기 때문에 문제 없이 작동하지만 track는 조건문 안에서 선언되었기 때문에 외부에서는 접근할 수 없다, 

따라서 console.log()에서 해당 값을 조회할 수 없게 되는 것이다.

 

3. const

const 키워드는 Java에서 final과 비슷하다고 생각하면 된다. 선언과 동시에 값이 정의되어야 하며, 한 번 정의된 값은 바꿀 수 없다는 불변의 특징이 있다.

const age = 30;

age = age + 10;
console.log( age );

위와 같이 코드를 작성하면 에러가 난다.

age라는 변수는 const로 선언되었기 때문에 30이라는 값에서 바꿀 수 없다.

하지만 age라는 값을 40이라는 값으로 바꾸려고 시도했기 때문에 에러가 난다.

 

결론

일반적으로 변수를 선언할 때 상황에 따라 let과 const를 사용한다고 한다.

var는 잘 사용하지 않는데, 그 이유가 의도치 않게 같은 이름의 변수를 선언하는 경우를 막기 위해서라고 한다.

따라서, 절대 변하지 않는 상수를 선언할 때는 const를 사용하며, 일반적인 변수를 사용할 때는 let을 사용하는 것이 좋은 방법이라고 한다.