var
var name = "Kim";
name = "Lee";
console.log(name)
// Lee
var
를 사용해 변수를 선언하면 재할당이 가능하여 값이 바로 변경된다. var
의 이런 동작은 하나의 파일을 여러 사람이 작성하는 협업 시에 특히 문제가 될 수 있다.
이를 보완하기 위해 ES6에 등장한 것이 const
와 let
이다.
const
const
로 변수를 한 번 정의하면 읽기만 가능하고 재할당이 불가하다.
const name = "Kim";
name = "Lee";
// Error: "name" is read-only
그러나 경우에 따라 변경이 되기도 하므로 완벽히 안전하지는 않음을 참고한다.
const person = {
name: "Kim"
};
person.name = "Lee"; // const로 선언한 객체의 값을 변경한다.
console.log(person)
// Object {name: "Lee"} - 값이 변경되었다.
let
const
와 함께 ES6에 도입된 let
은 var
와 마찬가지로 재할당이 가능하다.
let name = "Kim";
name = "Lee";
console.log(name)
// Lee
그렇다면 let
과 var
의 차이는 무엇일까?
TDZ, Temporal Dead Zone)
(1)
var myName = "Lee";
console.log(myName);
// Lee
(2)
console.log(myName);
var myName = "Lee";
// undefined
(3)
console.log(myName);
// ReferenceError: myName is not defined
(1)은 정상적인 코드이다.
(2)에서는 변수에 값을 할당하기 전에 콘솔 출력이 먼저 일어난다. 자바스크립트는 원칙적으로는 코드를 위에서부터 차례대로 실행하므로, 변수에 값이 할당 되기 전에 변수를 출력하면 undefined
인 것이 그럴듯해 보인다.
그런데 (3)을 보면, (2)처럼 변수에 값이 할당 되지 않은 상태에서 콘솔 출력이 일어나는데 undefined
가 아닌 레퍼런스 에러가 나온다. 정의된 적이 없다는 뜻이다.
생각해보면 자바스크립트는 위에서부터 차례대로 코드를 실행하니 (2)에서도 레퍼런스 에러가 발생하는 것이 합당한데 왜 undefined
를 출력하는 것일까? 이는 호이스팅(hoisting) 때문이다.
(Hoisting)
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.
호이스팅은 코드 실행 이전에 변수 및 함수 선언을 스코프 맨 위로 끌어올려두는 자바스크립트의 매커니즘이다.
호이스팅의 원리에 따라 위 (2)의 코드는 실제로 이렇게 동작했다.
var myName;
console.log(myName);
myName = "Lee";
// undefined
var
로 선언한 변수가 우선 맨 위로 끌어 올려진다. 그리고 두번째 줄에서는 아직 값이 할당되지 않았으므로, 호이스팅 때문에 변수 자체가 not defined
는 아니지만 값이 undefined
인 상태에서 콘솔에 출력된 것이다.
명백히 오류가 있는 코드인데 에러가 출력되지 않으니 코드 작성자는 undefined
라는 단서 만으로 어디가 잘못 되었는지 파악이 어려울 수 있다. 이는 바람직한 동작이 아니다. let
은 이 점을 보완한다.
(TDZ)
console.log(myName)
let myName = "Lee";
// Uncaught ReferenceError: myName is not defined
같은 코드를 let
으로 작성하면undefined
가 아닌 명확한 에러를 출력한다. 이것이 let
이 var
의 약점을 보완하는 지점이다.
ES6의 let
으로 변수를 선언하면, 변수에 값이 할당되기 이전까지 일시적 사각지대(TDZ)에 갇히도록 되어있다. 그러므로 값을 참조할 수 없으니 레퍼런스 에러가 발생한다.var
를 사용했을 때와는 달리, 에러 메시지를 통해 오류를 쉽게 파악할 수 있으므로 완전히 var
를 대체하도록 권장된다.
var
의 운명이미 var
로 작성되어 있는 프로그램들이 있으니 var
가 세상에서 완전히 사라지지는 않겠지만 쓰임 상 더 이상 필요하지 않다는 것이 중론이다.
const
를 디폴트로 사용하는 것이 가장 확실하며, 재할당이 필요한 경우에 한해 let
을 사용하는 것이 좋다.