Frontend/javaScript

[JavaScript] 호이스팅(Hoisting)

dddzr 2024. 7. 5. 17:22

호이스팅(hoisting) 이란?

  • 자바스크립트에서 변수와 함수의 선언이 해당 스코프의 최상단으로 끌어올려지는 것처럼 동작하는 특성.
  • 선언은 스코프의 최상단으로 옮기지만, 초기화(할당)는 그 위치에서 그대로 이루어진다.
  • 호이스팅은 함수와 변수를 다르게 처리.

 

호이스팅(hoisting) 원인

  • 실행 컨텍스트의 생성 단계에서 변수와 함수의 선언이 미리 처리되기 때문에 발생.
  • 실행 컨텍스트는 자바스크립트 코드가 실행되는 환경을 정의하며, 함수 호출 또는 전역 코드가 실행될 때마다 생성.
  • 실행 컨텍스트는 생성 단계와 실행 단계로 나뉜다.
    • 생성 단계 (Creation Phase)
      • 변수와 함수 선언 처리: 실행 컨텍스트가 생성될 때, 자바스크립트 엔진은 먼저 현재 스코프 내의 변수와 함수 선언을 찾아서 메모리에 등록, 이때 변수는 undefined로 초기화되고, 함수 선언은 실제 함수 객체로 초기화된다.
      • Lexical Environment 구성: 선언된 변수와 함수는 Lexical Environment에 등록. 이 환경은 스코프 내의 식별자와 그 바인딩을 저장한다.
    • 실행 단계 (Execution Phase)
      • 코드 실행: 생성 단계가 완료된 후, 자바스크립트 엔진은 코드의 나머지를 순차적으로 실행. 이때 변수 할당과 함수 호출이 이루어진다.

 

변수 호이스팅 (Variable Hoisting)

자바스크립트에서 변수 선언은 `var`, `let`, `const` 키워드를 사용하여 이루어짐.

`var`로 선언된 변수는 호이스팅의 영향을 받지만, `let`과 `const`로 선언된 변수는 호이스팅의 영향을 받지 않는다.

- var

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

  위 코드에서 `var a` 선언이 최상단으로 호이스팅되어 실제로는 다음과 같이 동작.

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

선언은 호이스팅되지만, 초기화는 그 위치에서 이루어진다.

- let, const

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

  `let`과 `const`로 선언된 변수는 호이스팅되지만, 초기화 전에 접근하려고 하면 `ReferenceError`가 발생. 이는 "일시적 사각지대(TDZ, Temporal Dead Zone)"에 의해 발생함.

 

함수 호이스팅 (Function Hoisting)

함수 호이스팅은 함수 선언 방식에 따라 다르게 동작한다.

함수 선언과 함수 표현식의 두 가지 주요 방식이 있다.

- 함수 선언문 (Function Declaration)

  console.log(myFunc()); // "Hello, world!"
  function myFunc() {
    return "Hello, world!";
  }

함수 선언은 완전히 호이스팅됨. -> 함수 선언 이전에 함수를 호출할 수 있다.

- 함수 표현식 (Function Expression)
 함수 표현식은 변수 호이스팅처럼 동작. -> 함수 표현식이 할당되기 전에는 변수만 호이스팅되고 초기화되지 않음.

console.log(myFunc()); // TypeError: myFunc is not a function
var myFunc = function() {
  return "Hello, world!";
}

 

 

이처럼 자바스크립트의 호이스팅은 함수와 변수 선언에 다른 방식으로 적용됩니다. 이를 이해하면 코드를 작성할 때 예기치 않은 동작을 방지할 수 있습니다.

 

 

*함수 표현식에서 let 또는 const를 사용할 경우

변수의 경우와 같게 `ReferenceError`가 발생한다.

console.log(myFunc); // ReferenceError: Cannot access 'myFunc' before initialization
let myFunc = function() {
  return "Hello, world!";
};
console.log(myFunc()); // "Hello, world!"

'Frontend > javaScript' 카테고리의 다른 글

JavaScript 모듈 사용  (0) 2025.04.06
JavaScript 코드 실행 순서 & 실행 타이밍 제어  (0) 2025.04.06
iframe sesstion timeout  (0) 2023.10.13
[javaScript] file-saver 파일 다운로드  (0) 2023.10.02
checklist (vue3)  (0) 2023.07.20