ES5까지는 var 키워드만 사용하여 변수 선언이 됐었다.
이로인해 몇 가지 문제가 발생했는데,
변수 중복 허용
var x = 1;
var y = 1;
// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
// 초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해
// var 키워드가 없는 것처럼 동작한다.
var x = 100;
// 초기화문이 없는 변수 선언문은 무시된다.
var y;
console.log(x); // 100
console.log(y); // 1
변수의 중복 허용으로 의도와 다르게 동작하는 경우가 발생할 여지가 있다.
함수 레벨 스코프
var 키워드는 함수 코드 블록 안에서만 지역 스코프를 가진다.
즉, 전역 스코프 계층에 있는 다른 변수가 의도와 다르게 변경이 될 수도 있다.
var x = 1;
if (true) {
var x = 10;
}
console.log(x); // 10
변수 호이스팅
변수 선언 이전에 호이스팅으로 인해 변수를 사용할 수 있다.
에러가 발생하지 않지만, 가독성을 떨어뜨리고 얘기치 못한 오류를 만들 수 있다.
console.log(foo); // undefined
foo = 123;
console.log(foo); // 123
var foo;
ES6에서 새롭게 도입된 변수 선언 키워드다.
변수 중복 선언 금지
let 키워드로 선언할 경우 더이상 중복 선언을 할 수 없다.
블록 레벨 스코프
var 키워드는 함수레벨 안에서만 지역 스코프를 가졌지만, let으로 만들 경우 모든 코드 블록에서 지역 스코프를 갖게 된다.
let foo = 1; // 전역 변수
{
let foo = 2; // 지역 변수
let bar = 3; // 지역 변수
}
console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined
변수 호이스팅
var 키워드로 선언한 변수와 달리 let 키워드는 호이스팅이 발생하지 않는 것 처럼 동작한다. 호이스팅이 일어나지 않는 것은 아니다.
console.log(foo); // ReferenceError: foo is not defined
let foo;
var 키워드는 선언 단계와 초기화 단계가 런타임 이전에 자바스크립트 엔진에 의해 한번에 진행됐다.
let 키워드는 선언 단계와 초기화 단계가 분리되어 진행된다.
let foo = 1; // 전역 변수
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2;
}
호이스팅이 일어나지 않는다면 위 코드는 1을 출력 후 블록 스코프 안에서 foo가 선언이 돼야 한다.
하지만, 에러가 발생한다는 것은 호이스팅이 일어나 참조 에러를 발생시킨다.
전역 객체와 let
var 키워드로 선언한 전역 변수와 객체들은 전역 객체 window의 프로퍼티가 된다.
let로 선언한 전역 변수는 전역 객체의 프로퍼티가 아닌 개념적인 블록 내에 존재한다.
const 키워드는 상수를 선언하기 위해 사용한다.
반드시 선언과 동시에 초기화 해야 한다.
const foo = 1;
const bar; // SyntaxError: Missing initailizer in const declaration
재할당 금지
상수기 때문에 재할당 할 수 없다.
상수는 재할당이 금지된 변수다.
단, const 키워드로 객체를 선언할 시 변수에 새로운 객체를 선언할 순 없지만, 선언된 객체 내의 값을 변경할 순 있다.
const person = {
name: "Lee"
}
person.name = "Mos";
console.log(person); // {name: "Mos"}
person = {}; // Assignment to constant variable