var 키워드의 문제점 정리
- 변수 중복 선언 허용
- 함수 레벨 스코프
- 블록 레벨 스코프가 아니어서 if for 문에 선언하면 변수 중복 선언 허용 특징과 콜라보해서 의도치 않게 변수값 재할당하게됨
- 변수 호이스팅 발생
- 선언 코드 전에 접근 가능하고 값은 undefined
이러한 var의 단점을 보완하고자 나온 선언 키워드가 let
-
중복 선언 금지 → SyntaxError 발생
-
블록 레벨 스코프
-
변수 호이스팅 동작 막아줌
- 선언 코드 전에 접근 시 → ReferenceError: xxx is not defined
- var는 암묵적으로 선언 단계와 초기화 단계가 한번에 진행되었음
- 그래서 선언하면 undefined로 초기화되어 접근 가능했던 것
- let은 선언 단계와 초기화 단계가 분리
- 선언 단계 이후 초기화 단계전까지 ReferenceError를 내면서 선언한 변수에 접근 할 수 없는 구간을 일시적 사각지대라고 부름 (TDZ: Temporal Dead Zone)
- 다만 변수 호이스팅 동작을 막아줄 뿐 없는 것은 아니다
let foo = 1 // 전역변수 { console.log(foo); // ReferenceError: Cannot access 'foo' before initialization let foo = 2; // 지역 변수 }
let이 변수 호이스팅이 일어나지 않는다면 console.log(foo)는 스코프 체이닝을 타고가서 전역변수 foo의 값을 참조했어야 한다. 그러나 블록 스코프 안에서 지역변수
let foo의 호이스팅이 일어났기 때문에 전역변수가 아닌 지역변수let foo에 접근하게 되어 참조에러를 발생시킨것var foo = 1 { console.log(foo); // 1 var foo = 2; }
var로 선언한 경우 var는 함수 레벨 스코프이기 때문에 전역 변수인
var foo와 동일한 스코프를 가진다. 따라서 전역변수 foo와 전역변수 foo는 아래와 같이 호이스팅된다var foo; // 중복 선언된 변수는 무시된다 var foo; // 호이스팅된 선언 (값은 undefined) foo = 1; // 초기화는 원래 위치에서 발생 { console.log(foo); // 1 foo = 2; // 재할당 (새로운 변수가 아님) }
let foo = 1 // 전역변수 { console.log(foo); -> ? let foo = 2; // 지역 변수 }
var foo = 1 // 전역변수 { console.log(foo); -> ? var foo = 2; // 지역 변수 }