호이스팅 (Hoisting)
“Before run all the code, the browser first get all declarations, hoisting is the name of this process.”
scope(스코프) 안에서의 변수 선언을 최상위에서 선언한 것과 동등하다는 의미를 가진다. 즉, 변수가 선언되기 이전에 변수를 사용하면, 변수가 사용된 블럭 범위의 맨 위로 변수를 끌어올린다는 말이다.
호이스팅(Hoisting)은 JavaScript 인터프리터가 코드를 해석할 때 변수 및 함수의 선언 처리, 실제 코드 실행 두 단계로 나눠서 처리하기 때문에 발생하는 현상이다. JavaScript 인터프리터가 내부적으로 코드를 이런 방식으로 처리한다는 것일 뿐, 실제 코드 라인이 변경되거나 하는 건 절대 아니다.
호이스팅 | 초기값 | 스코프(scope) | |
함수 선언 | ✅ YES | 실제 함수 | Block |
var | ✅ YES | undifined | Function |
let, const | 🚫 NO | <uninitialized>, TDZ(Temporal Dead Zone) | Block |
함수 표현식, arrow 함수 | var나 let/const를 사용하는지 유무에 따라 다름 |
var
왜 undefined가 출력이 될까? 그 이유는 var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어지기 때문이다. 즉, 스코프에 변수를 등록하고 (선언 단계), 등록된 변수에 메모리를 할당하고 undefined로 초기화(초기화 단계)하는 것이 동시에 일어난다는 것이다. 변수가 등록되어 있고, 할당만 아직 안된 단계이기 때문에 초기화 된 값인 undefined가 출력되는 것이다.
💡 var의 경우에는 함수 스코프라는 것을 유의하자. hoisting에 의해 의도하지 않은 undifined 값이 나올 수 있다.
함수
1. 함수 선언문
함수 선언문은 호이스팅 영향으로 끌어올려지기 때문에 정상 작동한다.
2. 함수 표현식
var의 경우에는 TypeError가 발생한다. 이는 위의 var의 호이스팅 결과가 undifined가 나오는 이유와 동일하다. count가 아직 할당이 안되어 있기 때문에 undifined로 함수 값이 될 수 없다.
이 결과 역시 let과 const에 의한 결과이다.
함수 표현식의 경우 호이스팅의 결과가 var를 사용하는지 혹은 let/const를 사용하는지에 따라 달라짐을 알 수 있다.
let, const
let과 const 또한 var과 동일하게 hoisiting이 된다. 하지만 대부분 let과 const는 호이스팅(Hoisting)이 발생하지 않는다고 느낀다. 이유는 바로 let과 const에서 TDZ(Temporal Dead Zone)에 의해 제약을 받기 때문이다.
TDZ(Temporal Dead Zone) ?
TDZ은 선언 전에 변수에 접근하는 것을 금지한다. 선언은 되어있지만 아직 초기화가 되지 않아 변수에 담길 값을 위한 공간이 메모리에 할당되지 않은 상태를 말한다.
💡 실행 컨텍스트가 생성될 때 let/const 변수 선언은 Lexical Environment에 저장된다. Lexical Environment에 저장된 변수들은 초기화(값 바인딩)되기 전까지는 접근할 수 없는 TDZ 상태에 있게 된다. 반면에 var 변수 선언은 Variable Environment에 따로 저장되며, TDZ에 영향을 받지 않는다.
TDZ는 코드 예측 가능하게 하고 버그를 쉽게 찾아낼 수 있게 해준다. TDZ가 있기 때문에 const 객체가 우리가 원하는 바대로 작동하는 것이다.
참조
'JavaScript' 카테고리의 다른 글
[Javascript] Optional Chaining (0) | 2021.09.23 |
---|---|
[Javascript] 구조 분해 할당 (Destructing) (0) | 2021.09.15 |
[Javascript] 실행 컨텍스트 (Execution Context) (0) | 2021.09.13 |
[Javascript] 자바스크립트 엔진, 자바스크립트 런타임 (0) | 2021.09.08 |
[Javascript] 프로토타입(prototype) (0) | 2021.09.03 |