변수 선언 키워드는 var, const, let이 있다.
const와 let은 ES6에서 추가되었다.
let
키워드와 다른점: 변수 블록을 고려하지 않고 현재 함수 (또는 전역 스코프) 어디에서나 접근할 수 있는 변수를 선언한다.var x = 1;
if (x === 1) {
var x = 2;
console.log(x);
// expected output: 2
}
console.log(x);
// expected output: 2
var x = 'global';
console.log(this.x); // "global"
bla = 2
var bla;
// 위 선언을 다음과 같이 암묵적으로 이해하면 됩니다:
var bla;
bla = 2;
var
키워드와 다른점: let을 사용한 표현식 내로 범위가 제한된다.function varTest() {
var x = 1;
if (true) {
var x = 2; // 같은 변수!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 다른 변수
console.log(x); // 2
}
console.log(x); // 1
}
Temporal Dead Zone
var
로 선언된 변수는 선언 전에 쓸 수 있다.(undefined)function do_something() {
console.log(bar); // undefined
console.log(foo); // ReferenceError
var bar = 1;
let foo = 2;
}
let
변수 선언 코드가 그 변수에 접근하는 함수보다 아래에 위치하지만, 함수의 호출 시점이 사각지대 밖이므로 정상 작동한다.{
// TDZ가 스코프 맨 위에서부터 시작
const func = () => console.log(letVar); // OK
// TDZ 안에서 letVar에 접근하면 ReferenceError
let letVar = 3; // letVar의 TDZ 종료
func(); // TDZ 밖에서 호출함
}
var
를 let
으로 재선언var
가 블록 최상단으로 끌어올려져 변수 재선언을 하는 것과 같아지기 때문에 SyntaxError가 발생한다.let x = 1;
{
var x = 2; // 재선언으로 인한 SyntaxError
}
// const는 오브젝트에도 잘 동작합니다
const MY_OBJECT = {'key': 'value'};
// 오브젝트를 덮어쓰면 오류가 발생합니다
MY_OBJECT = {'OTHER_KEY': 'value'};
// 하지만 오브젝트의 키는 보호되지 않습니다.
// 그러므로 아래 문장은 문제없이 실행됩니다
MY_OBJECT.key = 'otherValue'; // 오브젝트를 변경할 수 없게 하려면 Object.freeze() 를 사용해야 합니다
// 배열에도 똑같이 적용됩니다
const MY_ARRAY = [];
// 배열에 아이템을 삽입하는 건 가능합니다
MY_ARRAY.push('A'); // ["A"]
// 하지만 변수에 새로운 배열을 배정하면 에러가 발생합니다
MY_ARRAY = ['B']