왜 var 대신, const와 let을 사용하는 것을 권장할까?
크게 3가지 이유로 볼 수 있다.
var
로 선언한 변수는 중복 선언이 가능하다.
var a = 10;
...
var a = 'hello'; //OK
반면에, let
이나 const
로 선언한 변수는 재 선언이 불가능하다.
let b = 10;
...
let b = 'hi'; //SyntaxError: Identifier 'b' has already been declared
중복 선언이 가능해지면, 이미 선언한 변수명을 재사용하면서 코드가 꼬일 가능성이 매우 높아지고, 유지보수 또한 어려워진다.
따라서 let과 const를 통해 변수의 재사용 여부만 지정해주고, 재 선언을 하지 못하도록 막아줌으로써 코드의 안전성을 높일 수 있다.
변수의 유효 범위를 뜻한다. 위의 에러에서 보인 block-level scope
변수와 function-level scope
변수로 나눌 수 있다.
여기에서 var는 function-level scope,
let과 const는 block-level scope이다.
var
가 해당한다.
지역변수는 함수 내부에서 유효하며, 나머지는 모두 전역변수로 간주한다.
function funcLevel() {
var a = 10;
console.log(a);
}
funcLevel();
console.log(a); //ReferenceError: a is not defined
위와 다르게, 함수가 아닌 단순히 블럭 내부에서 선언된 변수는 전역변수로 취급한다.
if (condition) {
var a = 10;
console.log(a);
}
console.log(a); //10
ES6 문법에 새로 등장한 개념으로, let
과 const
가 해당한다.
함수 내부 뿐만 아니라 반복문, 조건문 등의 코드 블럭({}
로 구분된 경계)에서 선언된 변수도 지역 변수로 취급한다.
다른 말로, 블록 내부에서 선언된 변수들은 해당 블록 내에서만 접근이 가능하다.
let a = 'a';
if (condition) {
let b = 'b';
console.log(a); //a
console.log(b); //b
}
console.log(a); //a
console.log(b); //ReferenceError: b is not defined
많은 사람들이 사용하는 언어인 C
와 Java
도 변수들이 block-scope로 선언된다.
function-level scope는 코드의 복잡도가 더 높아질 가능성이 있으며, 이는 디버깅의 어려움과 가독성의 하락으로 이어진다. 또한 이는 곧 유지보수의 어려움과 이어질 가능성이 높다.
따라서 ES6 문법에서는 Block-level scope 사용을 권장하고 있다.
아래의 코드를 실행하면 어떻게 될까?
function sayHi() {
word = "Hello";
console.log(word);
var word;
}
sayHi();
위의 코드에서 word
변수는, 선언되기 전에 사용되고 있다. 그런데도 'Hello'가 정상적으로 출력이 된다.
위의 현상이 발생하는 이유는, 호이스팅
이라는 것으로 설명될 수 있다.
호이스팅이란, 스코프 안에 있는 선언들을 모두 스코프의 최상위로 끌어올리는 것을 말한다.
자바스크립트의 인터프리터는 함수의 선언, 할당, 실행을 따로 처리한다. 이 때, var
로 선언된 변수들은 모두 함수의 최상단으로 'hoist' 된다.
이 때에 hoist되는 것은 선언만이고, 할당은 hoist되지 않는다.
따라서 위의 코드는 실제 컴파일 과정에서 아래와 같이 변하게 된다.
function sayHi() {
var word; // hoist된 선언
word = "Hello";
console.log(word);
}
sayHi();
이와 같이 호이스팅 된 var 변수는 앞서 이야기 한 것처럼 전역 변수와 같은 범위를 가지고, 재할당과 재선언이 가능한 과도한 전역변수의 생성으로 이어지므로 코드가 복잡해질 여지가 많다.
cf) 그렇다면 let과 const는 hoisting 되지 않을까?
-> 아니다. let, const와 var의 주요한 차이점은, 값이 할당될 때까지의 과정에 있다.
undefined
상태이다.TDZ(Temporal Dead Zone)
에 있게 된다. 해당 단계에 있는 변수에 접근하게 되면 reference error가 발생한다.참고
https://eblee-repo.tistory.com/37
https://ko.javascript.info/var