호이스팅(Hoisting)이란 자바스크립트 함수 안에 선언된 변수들을 유효 범위 최상단에 선언하는 것을 말합니다.
function
), 이 때 새로운 'scope object'가 생성됩니다.var
)를 만나면 그것의 symbol 이름이 스코프 안에 만들어지고, 값은 undefined
로 할당됩니다.IR(Intermediate Representation : 소스 코드를 표현하기 위해 컴파일러 또는 가상 시스템에서 내부적으로 사용하는 데이터 구조 또는 코드입니다
참고:
console.log("hello");
var myname = "HEEE"; // var 변수
let myname2 = "HEEE2"; // let 변수
/* --- JS Parser 내부의 호이스팅(Hoisting)의 실행 순서 --- */
var myname; // [Hoisting] "선언"
console.log("hello");
myname = "HEEE"; // "할당"
let myname2 = "HEEE2"; // [Hoisting] 발생 X
foo();
foo2();
function foo() { // 함수선언문
console.log("hello");
}
var foo2 = function() { // 함수표현식
console.log("hello2");
}
/* --- JS Parser 내부의 호이스팅(Hoisting)의 순서 --- */
var foo2; // [Hoisting] 함수표현식의 변수값 "선언"
function foo() { // [Hoisting] 함수선언문
console.log("hello");
}
foo();
foo2(); // ERROR!!
foo2 = function() {
console.log("hello2");
} // "할당"
예시 출처 및 참고: https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
/* --- var 변수의 함수표현식 --- */
foo(); // TypeError: foo is not a function
var foo = function() {
console.log("hello world")
}
/* --- let/const 변수의 함수표현식 --- */
foo2(); // ReferenceError: foo2 is not defined
let foo2 = function() {
console.log("hello world2")
}
var myName = "hi";
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
var yourName = "bye";
console.log(typeof myName);
console.log(typeof yourName);
/** --- JS Parser 내부의 호이스팅(Hoisting)의 순서 --- */
// 1. [Hoisting] 변수값 선언
var myName;
var yourName;
// 2. [Hoisting] 함수선언문
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
// 3. 변수값 할당
myName = "hi";
yourName = "bye";
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "string"
var myName = "Heee"; // 값 할당
var yourName; // 값 할당 X
function myName() { // 같은 이름의 함수 선언
console.log("myName Function");
}
function yourName() { // 같은 이름의 함수 선언
console.log("yourName Function");
}
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "function"
예시 출처 및 참고: https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
우선 TDZ(Temporal Dead Zone)는 직역하면 '일시적 사각지대'라는 뜻으로, 선언 단계부터 초기화 시작 전까지의 구간을 말합니다. 이것이 호이스팅과 무슨 관련이 있냐구요?
앞서 함수표현식의 선언과 할당의 분리를 떠올린다면 조금 감이 올 수도 있을 것 같습니다. 하지만 조금 더 자세히 설명하자면 자바스크립트에서 변수가 어떻게 생성되는지에 대해 알아볼 필요가 있습니다.
자바스크립트에서 변수는 기본적으로 다음 3단계를 거쳐 생성이 됩니다.
실행 컨텍스트 : 코드가 실행되기 위해 필요한 환경
즉, 엄밀히 말하면 let/const도 호이스팅이 된다는 말입니다. 하지만 let/const의 선언과 초기화가 따로 진행되면서 생기는 일시적 사각지대(TDZ)때문에 호이스팅이 돼도 참조할 메모리가 없어서 Reference Error가 발생하는 것이라는 거죠!
- 호이스팅은 되지만 참조오류가 생기는 경우
let, const, class구문, class construtor()내부의 super()메소드 (상속받은 경우), 기본 매개변수(ES6)- 호이스팅도 되고 참조오류도 생기지 않는 경우
var, 함수 선언식, import
참고: https://yeonjewon.tistory.com/85
Q: var를 쓰면 혼란스럽고 쓸모없는 코드가 생길 수 있습니다. 그럼 왜 var와 호이스팅을 이해해야 하나요?
A: ES6를 어디에서든 쓸 수 있으려면 아직 시간이 더 필요하므로 ES5로 트랜스컴파일을 해야합니다. 따라서 아직은 var가 어떻게 동작하는지 이해하고 있으면 좋겠죠?