let, const & var의 hoisting

CGH96·2023년 1월 2일
0

JS

목록 보기
3/3

Hoisting이 무엇인가?

Hoisting이 정확히 무엇인지 구글링해보면 "함수나 변수 등이 해당 범위의 맨 위로 올라가는 것 같은 현상"이라는 사람도 있고, 혹은 "맨 위로 올라가는 것 같은 현상의 동작 원리 자체"를 호이스팅이라고 하는 사람도 있다.

이 애매한 상황을 해결하기 위해 MDN을 참고했다.

JavaScript Hoisting 은 인터프리터가 코드를 실행하기 전에 함수, 변수 또는 클래스 의선언 을 해당 범위의 맨 위로 이동하는 것처럼 보이는 프로세스를 나타냅니다.
물론 HoistableDeclaration으로 정의하지만 여기에는 function, function*, async functionasync function*선언만 포함됩니다.
[MDN] https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

결론

MDN을 참고해보면 ECMA spec.에 정식으로 등록된 것은 아니고 "함수나 변수 등이 맨위 올라가는 것처럼 보이는 현상"을 구어체적으로 표현하는 단어다.(Hoisting 자체가 합의된 용어가 아니기 때문에 여러 의견으로 갈리는 것이 당연한 것 같다.)


Hoisting의 원리

함수가 생성되면, 해당 함수에 대한 정보들을 모아놓은Excution Context가 생성된다. 이 때, 함수 내에 선언된 함수 선언식변수들이 Excution Context내에 있는 Lexical Environment에 저장된다. Lexical Environment에 미리 저장된 이 정보들을 통해 우리가 선언 코드보다 위에서 함수 선언식변수들에 접근할 수 있는 것이다.

Lexical Environment

Lexical Environment는 변수 식별자(variable-identifier)를 매핑하여 갖고있는 데이터 구조다.

<Lexical Environment와 Excution Context에 대한 정리>

https://velog.io/@tt8784/Excusion-Context-Closure-%EC%9A%94%EC%A0%90%EB%A7%8C


<함수 선언식 Hoisting>

hellowWorld라는 함수 선언식은 앞서 말했듯이 Excution Context의 생성단계에 Excution Context가 가지고 있는 Lexical Environment라는 곳에 저장된다.

Lexical Environment는 다음과 같은 코드를 가지게 된다.

그래서 JavaScript 엔진이 helloWorld()라는 함수를 만나게 되면, Lexical Environment에서 해당 함수를 찾아 실행시킬 수 있다.


<함수 표현식 Hoisting>

JavaScript에서는 함수 선언식만 Hoisting이 된다.(함수 표현식은 X)

따라서 위와 같은 경우에는 helloWold가 함수가 아닌 변수로서 저장이 되고, JavaScript엔진은 helloWorld의 값을 undefined로 저장하게 된다.


코드는 아래와 같이 바꿔줘야 작동한다.

<var 변수 Hoisting>

위 코드에서 a의 기대값이 3이지만 output은 undefined이다.
JavaScript에서의 hoisting은 선언을 hoisting하는 것이지, 초기화를 얘기하는 것은 아니다.

그렇다면 왜 undefined일까?

JavaScript엔진이 var변수 선언을 만나면 이것은 Lexical Environmentundefined로 초기화해서 추가한다.

그리고 a3으로 초기화 하는 코드를 만나면 Lexical Environment에서도 a의 값을 3으로 업데이트한다.




<let, const 변수 Hoisting>

Example

Output

ReferenceError가 발생한다. 왜일까?

let, const도 마찬가지로 Lexical Environment에 등록된다. 하지만 undefined로 초기화 되지 않고 uninitialized상태로 저장된다

그리고 let, constuninitialized상태에서 runtime에 값이 동적으로 정해진다.
즉 우리는 엔진이 선언된 코드를 만나 값이 정해지기 전까지 해당 변수에 접근할 수 없다.
이것을 Temperal Dead Zone이라고 부른다.

[참고한 블로그]
https://blog.bitsrc.io/hoisting-in-modern-javascript-let-const-and-var-b290405adfda

0개의 댓글