[JS] 호이스팅(Hoisting)

heyday.xz·2024년 8월 11일
1
post-thumbnail

호이스팅

호이스팅(Hoisting)은 Javascript의 기본 동작 방식으로, 변수 선언과 함수 선언이 실제 코드 실행 전에 해당 스코프의 최상단으로 끌어올려지는 것처럼 동작하는 현상이다.
실제로 코드가 이동하는 건 아니고, 자바스크립트의 실행 컨텍스트가 변수를 메모리 공간에 미리 할당하기 때문에 발생하는 현상이다.

그러나 변수의 초기화는 호이스팅되지 않고, 선언만 호이스팅된다.

변수 호이스팅

변수 호이스팅은 var, let, const 로 선언된 변수에서 다르게 나타난다.

var 변수의 호이스팅

console.log(a); // undefined
var a = 5;
console.log(a); // 5

위의 코드에서 var a = 5;var a;a = 5;로 분리된다.
var a; 는 최상단으로 호이스팅되고 a = 5; 는 원래 위치에 남아있게 된다.
따라서 첫 번째 console.log(a);undefined 를 출력한다.

호이스팅 된 형태:

var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5

letconst 의 호이스팅

letconst로 선언된 변수도 호이스팅되지만, var 와는 달리 초기화 전에 접근하려 하면 ReferenceError가 발생한다. 이를 "일시적 사각지대(Temporal Dead Zone, TDZ)"라고 한다.

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;

함수 호이스팅

함수 선언문으로 정의된 함수는 코드의 최상단으로 완전히 끌어올려지기 때문에, 함수 선언 전에 해당 함수를 호출할 수 있다.

console.log(myFunc()); // "Hello, World!"

function myFunc() {
  return "Hello, World!";

}

위의 코드에서 function myFunc() { ... } 전체가 호이스팅되기 때문에 console.log(myFunc());가 정상적으로 실행된다.

호이스팅 된 형태:

function myFunc() {
  return "Hello, World!";
}

console.log(myFunc()); // "Hello, World!"

하지만 함수 표현식(var, let, const에 함수 리터럴을 할당하는 경우)은 변수 호이스팅 규칙을 따른다.

console.log(myFunc()); // TypeError: myFunc is not a function

var myFunc = function () {
  return "Hello, World!";
}

위 코드에서 var myFunc가 호이스팅 되었지만, 초기화 전에 함수 호출이 시도되었기 때문에 undefinedfunction으로 호출되어 TypeError가 발생한다.

일시적 사각지대(Temporal Dead Zone, TDZ)

일시적 사각지대는 letconst 변수에서 발생하며, 변수 선언이 실제로 이루어지기 전까지 그 변수에 접근할 수 없는 구간을 의미한다.

{
    // TDZ starts at beginning of scope
    console.log(x); // ReferenceError: Cannot access 'x' before initialization
    let x = 30; // End of TDZ
  	console.log(x); // 30
}

TDZ 는 코드가 작성된 위치가 아닌 실행 순서에 따라 영역이 달라진다.

 // TDZ starts at beginning of scope
function printValue() {
    console.log(value); // ReferenceError: Cannot access 'value' before initialization
}

printValue();

let value = 10; // End of TDZ

printValue(); // 10

첫번째 printValue 함수를 호출했을 때, value 변수는 아직 선언되지 않았다. 자바스크립트 엔진은 이 변수가 TDZ 에 있다고 판단하고 ReferenceError를 발생시킨다.
let value = 10 을 선언하면서 TDZ가 해제되고, 두번째 printValue 함수를 호출했을 때 정상적으로 10 이 출력된다.

1개의 댓글

comment-user-thumbnail
2024년 8월 11일

호잇!스팅

답글 달기