출처 모던 자바스크립트 Deep Dive을 보고 정리한 내용입니다.
ES6 이전까지 사용된 var 키워드는 다음과 같은 문제점을 야기했다.
var x = 1;
var x = 100;
console.log(x); //100
var i = 100;
for(var i = 0; i < 5; i++) {
console.log(i); //0 1 2 3 4
}
console.log(i); //5
console.log(x); //undefined
x = 10;
console.log(x); //10
var x;
var x = 10;
console.log(window.x); //10
ES6 이후 새롭게 등장한 let과 const키워드는 기존 var 키워드로 생성한 변수들이 갖는 문제점들을 해결해주었다.
let x = 1;
let x = 100; //SyntaxError
let i = 10;
if(i === 10) {
i = 100;
console.log(i); //100
}
console.log(i); //10
console.log(x); //ReferenceError
let x;
console.log(x); //undefined
x = 10;
console.log(x); //10
위 코드를 보았을 때, 변수 호이스팅이 일어나지 않는것 처럼 보인다. var 키워드 변수는 런타임 이전에 '선언 단계'와 '초기화 단계'가 한번에 이루어졌다면 let 키워드로 선언한 변수는 '선언 단계'와 '초기화 단계'가 분리되어 진행되며 초기화 단계는 변수의 선언에 도달했을 때 이루어지다. 따라서 초기화 단계가 실행되기 전에 변수를 참조한다면 참조 에러를 발생시킨다. 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대(Temporal Dead Zone)라고 한다.
선언 단계 -> 일시적 사각지대 -> 초기화 단계 -> 할당 단계의 순서로 진행되며 선언 단계와 일시적 사각지대에서 변수 참조가 불가능 하고, 초기화 단계에서 undefined로 초기화된다.
let x = 10;
console.log(window.x); //undefined
const 키워드는 상수를 선언하기 위해 사용된다. 상수란 변경될 수 없는 값을 말하며, 변경이 불가능하기 때문에 선언과 동시에 초기해야만 한다. 그렇기 때문에 재할당이 불가능하다.
const x = 1;
x = 2; //TypeErrorconst
y; //SyntaxError
그러나 const 키워드로 선언된 객체의 프로퍼티는 변경이 가능하다. 그러나 재할당은 불가능하다.
const obj = { name: 'aa' };
obj.name = 'JKCho';
console.log(obj.name); //'JKCho'
obj = { age: 15 }; //TypeError
즉, const 키워드는 재할당을 금지할뿐 "불변"을 의미하지는 않는다.