let, const

ES6부터 변화된 변수 생성 방식과 원인에 대해서 살펴본다.

var, let, const

기존에 사용하던 변수 선언 방식은 다음과 같이 var 키워드를 사용한다.

var a = 10;
var b = "hello";

이 변수 선언 방식은 다음과 같은 문제가 있다.

  • 변수의 중복 선언이 가능하다.

  • 변수가 없는 경우와 변수가 선언만 된 경우 모두 undefined를 반환한다

  • 함수 레벨 스코프를 가진다.

위 문제들을 해결하기 위하여 const와 let이라는 키워드가 등장하였다.

  • const : 불변(immutable) 변수 선언 키워드

  • let : 가변(mutable) 변수 선언 키워드

var 중복 선언

var a = 10;
var a = "hello";
var a = 12 + 345;
console.log(a);

위 코드를 실행하면 마지막에 선언한 a의 계산 결과인 357이 콘솔에 출력된다. 자유로운 자바스크립트 문법 체계에서는 문제가 되지 않을 수 있으나 이는 개발자를 혼란스럽게 만든다.

var a = 10;
a = "hello";
a = 12 + 345;
console.log(a);

위와 같이 작성하면 a의 값이 변경되었음을 코드로 짐작할 수 있다. constlet 키워드를 사용하면 중복 선언이 불가능하다.

const a = 10;
const a = "hello";//Uncaught SyntaxError : Identifier 'a' has already been declared
const a = 12+345;//Uncaught SyntaxError : Identifier 'a' has already been declared
console.log(a);
let a = 10;
let a = "hello";//Uncaught SyntaxError : Identifier 'a' has already been declared
let a = 12+345;//Uncaught SyntaxError : Identifier 'a' has already been declared
console.log(a);

undefined 이슈

var로 변수를 선언할 경우 undefined 이슈가 발생할 수 있다.

console.log(b);//undefined
var b;
console.log(b);//undefined

위 코드를 실행하면 변수 선언 전, 후가 동일하게 undefined가 나온다. 이는 var로 선언한 변수가 호이스팅(hoisting) 되기 때문이다.

호이스팅

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 letconst로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.

호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.

출처 - MDN Web docs (https://developer.mozilla.org/ko/docs/Glossary/Hoisting)

호이스팅은 자바스크립트가 실행되는 가장 일반적인 방법이었으나, 프로그램이 점점 고도화되면서 변수에 있어서 가독성이 떨어진다는 단점이 발생하게 되었다.

const는 불변(immutable)이므로 반드시 값이 대입되어야 한다.

const b;//Uncaught SyntaxError: Missing initializer in const declaration

또한, 중복 선언도 불가능하다.

const b = "hello";
const b = "hi";//Uncaught SyntaxError: Identifier 'b' has already been declared

선언 전에 접근할 수도 없다.

console.log(b);//Uncaught ReferenceError: b is not defined
const b = "hello";

let은 가변이므로 선언만 해도 문제가 발생하지 않는다.

let b;//undefined

하지만 추가 선언을 하면 오류가 발생하므로 변수 선언은 한 번만 될 것이라 믿을 수 있다.

let b;
let b;//Uncaught SyntaxError: Identifier 'b' has already been declared

let 역시 const와 마찬가지로 선언 전에 접근할 수 없다.

console.log(b);//Uncaught ReferenceError: b is not defined
let b = "hello";

var 함수 레벨 스코프

var 키워드로 선언된 변수는 함수 상단에 호이스팅된다.

위 이미지 코드대로 함수를 만들어 실행하면 다음과 같이 출력된다.

10 '홀수' undefined

하지만 이는 정상적인 출력이라 보기 어렵다. 코드에는 함수 뿐 아니라 if와 else같은 블록(block) 레벨 스코프도 존재하기 때문이다.

현대 프로그래밍에서는 함수 레벨 스코프 뿐 아니라 블록 레벨 스코프도 중요하게 간주한다. 따라서 var로 변수를 선언하면 스코프의 혼동이 올 수 있어 명확한 코드 작성이 어렵다.

const 또는 let으로 코드를 변경하면 블록 레벨 스코프 범위로 제한하여 사용할 수 있으며, 선언 전에 접근할 수 없다.

function tmpFunc(){
    const a = 10;
    if(a % 2 == 0){
        const b = "짝수";
    }
    else {
        const c = "홀수";
    }
    console.log(a);//10
    console.log(b);//Uncaught ReferenceError: b is not defined
    console.log(c);//Uncaught ReferenceError: c is not defined
}

결론

특별한 이유가 없다면 constlet을 사용하여 변수를 처리하는 것이 좋다.

Last updated