var 키워드로 선언한 변수의 문제점
ES5까지 변수를 선언할 수 있는 유일한 방법은 var 키워드를 사용하는 것이였다.
변수 중복 선언 허용
- var 키워드로 선언한 변수는 중복 선언이 가능하다. (재할당 됨)
- ⇒ 의도치 않게 먼저 선언된 변수 값이 재할당 되어 변경되는 부작용이 발생했다.
var x = 1
var y = 1
var x = 100
var y
console.log(x,y)
초기화 문
함수 레벨 스코프
- var 키워드로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다.
- 함수 외부에서 var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수가 된다.
- ⇒ 함수 레벨 스코프는 전역 변수를 남발할 가능성을 높여, 의도치 않게 전역 변수가 중복 선언되는 경우가 발생한다.
변수 호이스팅
- var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작한다.
- 즉, 변수 호이스팅에 의해 var 키워드로 선언한 변수는 변수 선언문 이전에 참조할 수 있다.
- 단 할당문 이전에 변수를 참조하면 undefined를 반환한다.

let 키워드
위의 var 키워드의 단점을 보완하기 위해 ES6에서는 let, const 를 도입했다.
변수 중복 선언 금지
- 이름이 같은 변수를 중복 선언하면 문법 에러가 발생한다.
블록 레벨 스코프
변수 호이스팅
- let 은 마치 변수 호이스팅이 발생하지 않는 것 처럼 동작한다.
- let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
- 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 먼저 실행되지만,
- 초기화 단계는 변수 선언문에 도달했을 때 실행된다. ⇒ undefined 조차 할당되지 않았기에 에러 발생
- TDZ (일시적 사각지대) : 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간

전역 객체와 let
- var 키워드로 선언한 전역 변수와 전역 함수 ,암묵적 전역은 전역 객체 window 의 프로퍼티가 된다.
- let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아니다. 즉, window.foo와 같이 접근할 수 없다.
- let 전역 변수는 보이지 않는 개념적인 블록, (전역 렉시컬 환경) 내에 존재 하게 된다.
const 키워드 (let과의 차이점)
상수를 선언하기 위해 사용하지만, 반드시 상수만을 위해 사용하진 않는다
선언과 초기화
- const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야 한다.
- let 과 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것 처럼 동작한다.
재할당 금지
- const 키워드로 선언한 변수는 재할당이 금지 된다.
상수
- const 키워드로 선언한 변수에 원시 값을 할당한 경우 변수 값을 변경할 수 없다.
- ⇒ 원시 값은 변경 불가능한 값이고, const 키워드는 재할당이 금지되기 때문이다.
const 키워드와 객체
- const 키워드에 객체를 할당한 경우 값을 변경할 수 있다.
var vs. let vs. const 권장법
- ES6를 사용한다면 var 키워드는 사용하지 않는다.
- 재할당이 필요한 경우에 한정해 let 키워드를 사용한다.이때 변수의 스코프는 최대한 좁게 만든다.
- 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체에는 const 키워드를 사용한다.