Primitive Type과 Reference Type
자바스크립트 엔진은 변수 선언을 다음과 같은 2단계에 거쳐 수행한다.
변수를 선언한 이후, 아직 변수에 값을 할당하지 않았다. 따라서 변수 선언에 의해 확보된 메모리 공간은 비
어 있을 것으로 생각할 수 있으나 확보된 메모리 공간에는 자바스크립트 엔진에 의해 undefined라는 값이
암묵적으로 할당되어 초기화된다. 이것은 자바스크립트의 독특한 특징이다.
<aside> 💡
변수 이름은 어디에 등록되는가?
변수 이름을 비롯한 모든 식별자는 실행 컨텍스트에 등록된다. **실행 컨텍스트(execution context)**는 자바스크립트 엔진이 소스코드를 평 가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다.
자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리한다. 변수 이름과 변수 값은 실행 컨텍스트 내에 키/값 형식인 객체로 등록되어 관리된다. 자바스크립트 엔진이 변수를 관리하는 메커니즘은 13장 "스코프"와 23장 "실행 컨텍스트"에서 자세히 살펴볼 것이다.
</aside>
var
선언 단계와 초기화 단계가 동시에 진행된다.
호이스팅이 일어난다.
함수 레벨 스코프를 갖는다
let
선언 단계와 초기화 단계가 분리되어 있다.
호이스팅이 일어난다.
블록 레벨 스코프를 갖는다.
var은 웹 전역 영역에 영향을 줘 이전 어플리케이션이 다음 어플리케이션에 영향을 줄 수도 있다.
console.log(score); // undefinded
var score; // 변수 선언문
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 것을 변수 호이스팅이라고 한다.
변수 선언이 런타임이 아니라 그 이전 단계에서 실행되기 때문에, 발생하는 특징이다.
변수 선언 뿐만 아니라, var, let, const, function, function*, class 키워드를 사용한 모든 식별자에 적용된다.
TDZ란?
**TDZ(Temporal Dead Zone)**란, 임시사각지대라고도 부르며 변수가 선언되기 전의 코드 영역을 말한다. TDZ에 있는 변수에 접근하려고 하면 ReferenceError가 발생합니다. 이는 변수가 선언되기 전에 접근하는 것을 방지하기 위한 메커니즘입니다.
왜냐하면 TDZ는 코드의 예측 가능성을 높이고, 변수 선언과 초기화를 명확하게 구분하기 위해 존재하기 때문입니다. 이를 통해 코드의 안정성을 높일 수 있습니다.
TDZ와 호이스팅
let, const는 호이스팅은 되지만, 위에 예시와 같이 undefined가 출력되는 것이 아닌, ReferenceError가 발생한다. 그 이유는 let, const는 선언은 되었지만, 초기화가 되지 않았기 때문이다.
그렇다면 “선언”의 역할은 무엇일까? 선언의 역할은 JS 엔진에 ‘해당 변수가 사용될 예정이다’ 정도만을 알려주며, 잘못된 메모리 주소에 접근하는 것을 막아준다. 즉, 더 이상한 공간에 접근해 메모리에 치명타를 주지 않게 에러를 일으키는 쿠션 역할을 한다.
let과 var은 호이스팅이 되는가?
var는 호이스팅이 되지만, let과 const는 호이스팅되고, TDZ에 들어간다. TDZ에 있는 변수에 접근하려고 하면 ReferenceError가 발생합니다. 이는 변수가 선언되기 전에 접근하는 것을 방지하기 위한 메커니즘입니다.
이후 변수가 초기화가 되고 난 뒤에는 TDZ에서 벗어나 사용 가능하게 된다.