JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
출처 호이스팅 - MDN Web Docs 용어 사전
hoisting 명사
끌어 올리기, 들어올려 나르기.
단순하게 설명하자면 단어 뜻 처럼 스크립트 내 변수와 함수의 선언 순서에 상관 없이 순서가 '끌어올려~~'진 듯한 현상이다. 포인트는 물리적으로 '끌어올려'지는 것이 아니라 자바스크립트 엔진이 먼저 전체 코드를 한 번 스캔하고 실행컨텍스트에 미리 기록해 놓기 때문에 이런 현상이 발생하는 것이다.
function
함수를 호이스팅하는 예시를 보면 호이스팅의 개념을 쉽게 이해할 수 있다.
test(); // 이 코드가 과연 실행될까..?
function test() {
document.writeln("Hoisting");
}
test();
함수를 할당하는 function test(){...}
코드가 함수를 실행하는 test()
코드 보다 아래에 작성된 경우, 호이스팅 개념 없이 이론적으로 생각해 보면 맨 첫째줄 라인의 test()
는 실행되지 않아야한다.
하지만 JS는 함수를 Hoisting(끌어올려~~!!)
하기 때문에 최상단의 test()
코드도 정상 작동합니다.
위의 개념을 먼저 접근하고 변수 호이스팅을 보게 되면 호이스팅의 개념이 다소 헷갈릴 수 있다. 왜냐하면 변수가 호이스팅 될 때는 선언, 초기화
만 된채로 호이스팅 되고 할당
까지 호이스팅 되지 않기 때문이다.
console.log(name); // undefined
var name = "James";
console.log(name); //James
그래서 위의 예제에서는 var name = "James"
가 작성되기 전 console.log(name)
은 초기화 된 var name;
을 출력한다는 의미로 undefined
를 출력하는 것이다.
const
와 let
은 var
의 모호하고 too much로 유연한 문제점을 보완하기 위해 등장한 개념인 만큼 const
와 let
으로 변수가 선언되기 이전 라인에 해당 변수를 출력하는 코드를 작성한 경우 참조 오류
가 발생한다.
console.log(name); // ReferenceError
const name = "James";
console.log(name); // ReferenceError
let name = "James";
!!!하지만!!! 오류가 발생했다고 해서 const
와 let
으로 선언한 변수는 호이스팅의 예외가 되는 것은 아니다.
여기서 TDZ(Temporal Dead Zone)
에 대한 개념이 나온다.
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = "James";
다시 이 예제로 돌아와서, 최상단 콘솔 로그에서 에러가 발생했기 때문에 let name="James"
가 호이스팅이 안되는 것으로 보일 수 있다.
단순하게 말하자면 호이스팅이 안되는 것이 아니다. let
, const
로 선언한 변수는 호이스팅되었지만, !접근만!하지 못하게 된 것이다.
여기서 console.log(name)
가 작성된 라인, 해당 zone
을 일시적으로 죽은 구역
이라고 이해하면 된다.'name'의 선언문이 나오기 전까지는 'name'에 접근할 수 없다는 말이 된다.
참고
호이스팅 - MDN Web Docs 용어 사전
[코딩알려주는누나] 자바스크립트를 배우는데 아직도 let과 var의 차이를 모른다고? : 호이스팅
[코딩앙마]자바스크립트 중급 강좌 #1 - 변수, 호이스팅, TDZ(Temporal Dead Zone)