웹 디자인/JavaScript

자바스크립트 변수 선언 키워드 var let const 차이

K.두부 2023. 2. 11. 16:37
반응형

자바스크립트에서의 변수 선언은 var, let, const를 사용한다. java에서는 변수의 유형에 따라 int, String, double 등으로 선언하지만 자바스크립트에서는 위 3가지로 변수 선언이 이루어진다.  그렇다면 var, let, const는 어떤 차이점이 있을까? 

 

변수 선언 및 재할당 가능 여부

1. var [중복 선언 가능, 재할당 가능]

var tmp = 'Hello';
console.log(tmp); // Hello

var tmp = 'World';
console.log(tmp); // World

tmp = 'Hello World';
console.log(tmp); // Hello World

동일한 이름으로 중복 선언을 했는데도 에러가 발생하지 않고, 해당 변수를 다른 값으로 변경할 수도 있다. 유연한 변수 선언으로 편리함을 제공하지만 복잡한 프로젝트를 진행하게 되면 많은 문제를 일으킬 수 있다.

 

때문에 ES6 이후, 이 문제점을 보안하기 위해서 나온 변수 선언 키워드가 let, const 다.

 

2. let [중복 선언 가능, 재할당 불가능]

let tmp = 'Hello';
console.log(tmp); // Hello

let tmp = 'World';
console.log(tmp); // SyntaxError: Identifier 'tmp' has already been declared

let 키워드는 중복 선언을 하게 되면 SyntaxError가 발생한다.

 

let tmp = 'Hello';
console.log(tmp); // Hello

tmp = 'World';
console.log(tmp); // World

변수를 재할당하는 것은 문제가 없다. 

 

3. const [중복 선언 불가능, 재할당 불가능]

const tmp = "Hello";
console.log(tmp); // Hello

const tmp = "World";
console.log(tmp); // SyntaxError: Identifier 'tmp' has already been declared

const 키워드는 let 키워드와 동일하게 중복 선언이 불가능하다.

 

const tmp = "Hello";
console.log(tmp); // Hello

tmp = "World";
console.log(tmp); // Uncaught TypeError TypeError: Assignment to constant variable.

변수 재할당도 불가능하다.

 

키워드 var let const
중복 선언 여부 O O X
재할당 가능 여부 O X X

 

스코프 (Scope)

변수 선언 및 재할당 가능 여부 외에도 var 키워드와 let, const 키워드에는 스코프의 차이가 존재한다.

스코프를 간단하게 설명하자면 "식별자 접근 규칙에 따른 유효 범위"다. 쉽게 설명해서 식별자(변수, 함수, 클래스)에 접근할 수 있는 범위라고 생각하면 된다.

 

1. var [함수 레벨 스코프 (function-level scope)]

function func() {
    if (true) {
        var tmp = 6;
        console.log(tmp); // 6
    }
    console.log(tmp); // 6
}

func();
console.log(tmp); // Uncaught ReferenceError ReferenceError: tmp is not defined

var 키워드로 생성된 변수는 함수 내에서 선언했다면 함수 내에서만 참조할 수 있다.

 

2. let, const [블록 레벨 스코프 (block-level scope)]

function func() {
    if (true) {
        let tmp = 6;
        const tmp2 = 7;
        
        console.log(tmp);  // 6
        console.log(tmp2); // 7
    }
    console.log(tmp);  // Uncaught ReferenceError ReferenceError: tmp is not defined
    console.log(tmp2); // Uncaught ReferenceError ReferenceError: tmp2 is not defined
}

func();
console.log(tmp);  // Uncaught ReferenceError ReferenceError: tmp is not defined
console.log(tmp2); // Uncaught ReferenceError ReferenceError: tmp2 is not defined

함수, 조건문, 반복문, try/catch문 등의 모든 코드 블록 {···} 내부에서 선언된 변수는 해당 코드 블록 내부에서만 참조할 수 있다. 

 

호이스팅

호이스팅이란 코드가 실행되기 전에 선언된 변수 및 함수를 해당 스코프의 맨 위로 이동하는 것을 말한다.

 

호이스팅을 이해하기에 앞서 자바스크립트에서 선언된 변수는 선언 단계 > 초기화 단계 > 할당 단계를 거쳐서 생성된다. 또한 변수뿐만 아니라 함수를 포함한 모든 선언은 호이스팅이 적용된다.

console.log(tmp); // undefined

var tmp = 'Hello';
console.log(tmp); // Hello

자바에서는 에러가 발생할 수 있는 상황이지만 자바스크립트에서는 호이스팅이 적용되서 tmp 변수 선언이 상단으로 올라게 된다.

 

var tmp;
console.log(tmp);

tmp = 'Hello';
console.log(tmp);

호이스팅이 발생해서 인터프리터에서는 이렇게 받아들인다는 것을 알 수 있다. var 키워드는 변수 선언 단계와 초기화 단계가 동시에 이루어지므로 에러가 발생하지 않는다.

 

console.log(tmp); // Uncaught ReferenceError ReferenceError: tmp is not defined

let tmp = 'Hello';

console.log(tmp); // Hello

let 키워드는 변수 선언 단계와 초기화 단계가 분리되어 진행된다. 런타임 이전에 자바스크립트 엔진에 의해서 선언 단계가 먼저 실행된 후에 초기화가 단계가 실행된다. 때문에 선언만 된 변수를 사용하려고 했기 때문에 참조 에러가 발생했다.

 

해당 스코프의 시작 지점부터 초기화 단계 시작 지점까지 변수를 참조할 수 없는 일시적 사각지대 (Temporal Dead Zone: TDZ) 구간에 존재한다.

 

console.log(tmp); // Uncaught ReferenceError ReferenceError: Cannot access 'tmp' before initialization

const tmp = 'Hello';

console.log(tmp); // Hello

const 키워드는 변수 선언 단계와 초기화 단계가 동시에 진행된다. let 키워드의 경우 자바스크립트 엔진에 이미 존재하지만 초기화가 진행되지 않았기 때문에 [변수] is not defined. 에러가 발생했지만, const 키워드의 경우 선언과 초기화가 동시에 이루어져야하지만 런타임 이전에는 실행될 수 없다. 때문에 초기화가 진행되지 않은 상태이기 때문에 Cannot access [변수] before initialization 에러가 발생한다.

 

★ 자바스크립트에서 변수를 선언할 경우 var 키워드보다는 let, const 키워드를 사용하는 게 좋다. 또한 변경하지 않는 값을 선언할 때는 const 키워드를 사용하는 걸 추천한다.

반응형