[JavaScript] Hoisting

2022. 3. 8.공부/JavaScript

728x90
function catName(name) {
	console.log("제 고양이의 이름은" + name + "입니다.")'
}
catName("호랑이");

/*
결과 : "제 고양이의 이름은 호랑이입니다."
*/
catName("호랑이");

function catName(name) {
	console.log("제 고양이의 이름은" + name + "입니다.");
}

/*
결과: "제 고양이의 이름은 호랑이입니다."
*/

 

자바스크립트에서는 함수의 호출이 함수 자체보다 앞서 존재하더라도 코드가 동작한다. JS에서는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당하기 때문이다. 이 현상을 JS의 Hoisting이라고 부른다. 호이스팅의 대상은 오직 "선언"이다. 선언 없이 호출 후 초기화를 진행한다면 호이스팅도 없고, 변수를 읽으려는 시도에서 에러가 발생한다. 

 

console.log(num); // 호출
num = 6; // 초기화
/*
에러 발생
*/

 

변수 선언 전에 호출을 시도하다면 메모리만 할당되어 기본 초기화 상태에서 호출이 되므로 undefined으로 표시된다.

 

console.log(num); // 호출
var num; // 변수 선언
num = 6; // 초기화
/*
결과 : 메모리가 할당되어 사용하는 시점에서 기본 초기화 상태이므로 undefined (let, const는 에러 발생)
*/

 

변수가 선언이 되면 이 변수는 호이스팅에 의해 변수가 속한 범위의 최상단으로 올라가게되고, 선언과 동시에 undifinend으로 초기화 되게된다. 이로 인해 에러가 아닌 undifiend가 출력되게 되며 변수 선언 전에 변수값을 참조할 수 있게 된다.

 

함수 실행 전에 호출해도 데이터는 읽힌다. (배열로 불러오지만 않는다면.. var, let, const 모두 동일)

 

let과 const에서도 호이스팅은 발생하는데, 선언과 동시에 초기화가 이루어져 메모리가 할당되는 var와는 달리 let에서는 선언과 초기화 사이에 '일시적인 사각지대'(TDZ)가 있어 "선언은 되어있지만 아직 초기화가 되지않아 값을 위한 공간이 메모리에 할당되지 않은 상태"로 관리되어 이때 해당 변수에 접근을 시도하면 에러 메세지를 띄우는 것으로 호이스팅을 막는다. 함수 선언식은 let이나 const로 선언해도 TDZ의 영향을 받지 않아 호이스팅된다. 아예 const는 문법 상으로 선언과 초기화를 동시에 해줘야 한다.

 

Ref.

https://developer.mozilla.org/ko/docs/Glossary/Hoisting