ES5 이전까지는 변수를 선언하기 위해 var 키워드 밖에 사용할 수 없었다.
지역 스코프
로 인정한다.const 키워드로 선언한 변수는 선언과 동시에 초기화가 이무어진다.
var는 선언하기 전에 사용할 수 있다.
아래의 예시로 선언만 호이스팅되고, 할당은 호이스팅 되지 않는 것을 알 수 있다.
var name; console.log(name); // undefined name = '이름';
let도 호이스팅이 사실 된다.
호이스팅의 정의는 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동하는 것이다.
그런데 왜 let과 const는 var처럼 동작하지 않을까? => 이유는 TDZ (Temporal Dead Zone) 일시적 사각지대 때문이다.
console.log(name); // Reference Error
let name = '이름';
TDZ 영역에 있는 변수들은 사용할 수 없다. let과 const는 TDZ 영향을 받는다. 즉, 할당을 하기 전까지는 사용할 수 없는 것이다.
이는 코드를 예측 가능하게 하고 잠재적인 버그를 줄일 수 있다.
TDZ 의 정확한 정의는 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 의미한다.
console.log(name); // TDZ
let name = '이름'; // 함수 선언 및 할당
console.log(name); // 사용 가능
호이스팅은 스코프 단위로 일어난다.
let age = 20;
function ageHandler () {
console.log(age); // TDZ
let age = 10; // 호이스팅 일으킨다
}
ageHandler();
1. 선언 단계
2. 초기화 단계
3. 할당 단계
선언과 초기화가 동시에 된다. 따라서 할당 전에 호출해도 에러가 나지 않고 undefined가 나온다.
선언 단계와 초기화 단계가 분리되어서 진행된다. 호이스팅되면서 선언 단계가 이루어지지만, 초기화 단계는 실제 코드에 도달했을 때 되기 때문에 reference error가 발생하는 것이다.
선언 단계과 할당이 동시에 되어야 한다. let과 var은 선언만 해두고 나중에 할당을 해도 된다. 왜냐하면 let과 var는 값을 바꿀 수 있기 때문.
const로 선언하면 바로 할당을 해야한다.
const name; // Uncaught syntax Error
name = '안녕';
함수 내에서 선언된 변수만 그 지역변수가 되는 것.
if문 안에서 var로 선언한 변수는 if문 밖에서도 사용이 가능하다. 하지만 let과 const는 블록 스코프이기 때문에 불가능하다.
const name = '이름';
if (name === '이름') {
var text = '안녕';
}
console.log(text); // '안녕'
var 키워드로 선언되어 있는 변수가 유일하게 벗어나오지 못하는 스코프는 함수이다.
블록 스코프 내에서 선언된 변수들은(지역변수
) 코드 블록 내에서만 유효하며 외부에서는 접근할 수 없다.
함수, if문, for문, try/catch, while 문 등을 의미한다.
호이스팅
: 변수를 선언하고 초기화 했을 때 선언 부분이 최상단으로 끌어올려지는 현상
var
은 함수레벨 스코프,let
과const
는 블록 레벨 스코프
var
: 중복 선언 가능 재할당 가능, 함수 레벨 스코프 , 선언하기 전에 사용 가능, 선언과 초기화가 동시에 됨
let
: 중복 선언 불가능, 재할당 가능, 블록 레벨 스코프
const
: 중복 선언 불가능, 재할당 불가능, 블록 레벨 스코프
let과 const도 변수 호이스팅이 되지만, 런타임에 컨트롤이 변수 선언문에 도달하기 전까지 일시적 사각지대 (TDZ)에 빠지기 때문에 참조할 수 없다.
변수 선언 시, 기본적으로 const를 사용하고 let은 재할당이 필요한 경우에 한정해 사용하는 것이 좋다.
왜냐하면 const 키워드를 사용하면 의도치 않은 재할당을 방지하기 때문에 안전하기 때문이다.
- 자바스크립트 Deep Dive