호이스팅(Hoisting)
: 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것
var
는 함수 스코프. 함수 내에서 선언되면 함수 밖에서 사용할 수 없다.
let
, const
는 블록 스코프. 모든 코드 블록에서 선언된 변수는 코드 블록 내에서만 유효하며 외부에서는 접근할 수 없다.
자바스크립트에서는 아래와같이 작성해도 에러가 나지 않는다.
console.log(name"); // undefined
var name = "홍길동";
파이썬에서는 에러 발생
print(name) # NameError: name 'name' is not defined
name = "홍길동"
자바스크립트에서 선언과 할당을 나중에 해주었는데도 오류가 나지 않는 이유는 호이스팅(Hoisting)
때문이다.
실제로 동작하는 모습은 다음과 같다.
var name;
console.log(name);
name = "홍길동";
변수의 선언 부분이 맨 위로 끌어올려지는 것을 호이스팅
이라고 한다.
undefined
가 출력되는 이유는 변수의 선언만 올려지고 할당은 올려지지 않기 때문이다.
즉, 선언은 호이스팅 되지만 할당은 호이스팅 되지 않는다.
그러나
let
과 const
의 경우 에러가 발생한다.
console.log(a);
const a = "AAA";
console.log(a);
var
와는 다른 결과를 내는 이유는 let
과 const
가 TDZ
의 영향을 받기 때문이다.
TDZ (Temporal Dead Zone)
는 변수 선언 이전에 변수를 참조하는 영역이다.
해당 영역에서 선언 이전에 참조한 변수는 참조 에러가 발생한다.
위의 코드의 경우 첫번째 줄이 TDZ에 해당한다.
일반적으로 변수의 생성과정은 3단계로 나눌 수 있다.
1. 선언
2. 초기화
3. 할당
var
는 선언과 동시에 undefined
로 초기화가 이루어진다.
let
은 선언과 초기화가 분리되어 진행된다. 호이스팅되면서 선언단계가 이루어지지만 초기화 단계는 실제코드에 도달했을 때 이루어지기 때문에 ReferenceError가 발생한다.
const
는 선언과 할당을 같이 해주어야한다.
이러한 이유로 var
는 에러가 발생하지 않지만 let
과 const
는 에러를 발생시킨다.
호이스팅, TDZ는 자바스크립트를 공부하면서 처음보는 개념이었다. 'TDZ를 모른 채 자바스크립트 변수를 사용하지 말라'는 말이 있을 정도로 중요한 내용인 것 같다. (https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/) 잘 기억하도록 하자
let
과 const
를 사용하면 예측 가능한 결과를 내고 버그를 줄일 수 있다고하니 let
과 const
를 지향하도록 하자