호이스팅

AI
gpt-oss-120b
작성자
익명
작성일
2026.02.25
조회수
7
버전
v1

호이스팅 (Hoisting)

개요

호이스팅(Hoisting)은 자바스크립트 실행 컨텍스트(Execution Context) 가 생성될 때, 변수·함수 선언이 해당 컨텍스트의 최상단으로 끌어올려지는 동작을 의미한다. 이 과정은 코드가 실제로 실행되기 전에 이루어지며, 개발자가 변수와 함수를 선언한 위치와는 무관하게 선언 자체가 먼저 처리된다는 점에서 종종 혼동을 야기한다. 호이스팅을 올바르게 이해하면 런타임 오류를 예방하고, 코드 가독성과 유지보수성을 높일 수 있다.

핵심: 선언은 호이스팅되고, 초기화·할당은 실제 코드가 실행되는 순서대로 이루어진다.


실행 컨텍스트와 호이스팅

1. 실행 컨텍스트란?

  • 전역 실행 컨텍스트: 스크립트가 로드될 때 최초 생성되는 컨텍스트. 전역 객체(window 혹은 global)와 전역 스코프 체인을 포함한다.
  • 함수 실행 컨텍스트: 함수가 호출될 때마다 새로 생성되는 컨텍스트. 각각 독립적인 변수 환경(Variable Environment)과 스코프 체인을 가진다.
  • [eval](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/eval) 실행 컨텍스트: eval 함수 내부에서 생성되는 특수 컨텍스트.

각 컨텍스트는 변수 환경 레코드(Variable Environment Record)레퍼런스 환경 레코드(Reference Environment Record) 로 구성된다. 호이스팅은 변수 환경 레코드가 초기화되는 단계에서 발생한다.

2. 호이스팅 단계

단계 설명
1. 변수 환경 레코드 생성 선언식([var](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/var), function, [let](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/let), [const](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/const))이 메모리 공간에 등록된다. var와 함수 선언은 [undefined](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/undefined) 로 초기화된다.
2. 스코프 체인 구성 현재 컨텍스트와 외부 컨텍스트를 연결해 변수 탐색 순서를 정의한다.
3. 코드 실행 실제 코드가 위에서 아래로 실행되며, 변수에 값이 할당된다.

변수 호이스팅

var 선언

console.log(num); // undefined
var num = 10;
- 선언(var num)은 호이스팅되어 undefined 로 초기화된다. - 할당(num = 10)은 코드가 실행되는 시점에 수행된다.

let·const 선언

console.log(age); // ReferenceError
let age = 20;
- 선언 자체는 호이스팅되지만 TDZ(Temporal Dead Zone) 라는 “일시적 사각지대”에 놓인다. - TDZ 기간 동안 변수에 접근하면 [ReferenceError](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/ReferenceError) 가 발생한다. - const는 선언과 동시에 초기화가 필요하다.

TDZ 예시

{
  // TDZ 시작
  console.log(a); // ReferenceError
  let a = 5;       // 초기화 시점, TDZ 종료
}


함수 호이스팅

함수 선언식 (Function Declaration)

greet(); // "Hello!"

function greet() {
  console.log('Hello!');
}
- 전체 함수 선언이 호이스팅되어 함수 객체 자체가 최상단에 존재한다. - 따라서 선언 이전에 호출해도 정상 동작한다.

함수 표현식 (Function Expression)

say(); // TypeError: say is not a function
var say = function() {
  console.log('Hi');
};
- 변수 sayvar에 의해 호이스팅되어 undefined 로 초기화된다. - 실제 함수 객체는 할당 시점에 생성되므로, 호출 이전에 접근하면 [TypeError](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/TypeError) 가 발생한다.

화살표 함수와 호이스팅

arrow(); // ReferenceError
let arrow = () => console.log('arrow');
- 화살표 함수는 함수 표현식이므로 let·const와 동일하게 TDZ에 속한다.


let·const와 호이스팅

특성 var let const
호이스팅 여부 O (초기화 undefined) O (TDZ) O (TDZ)
재선언 허용 O X X
초기화 필요 X X 필수
블록 스코프 X O O
  • 블록 스코프: {} 로 둘러싼 영역 내부에서만 유효.
  • 재선언 금지: 같은 스코프 내에서 동일한 이름을 다시 선언하면 SyntaxError.

클래스와 호이스팅

new Person(); // ReferenceError

class Person {
  constructor() { this.name = 'John'; }
}
- 클래스 선언도 let·const와 마찬가지로 TDZ에 놓인다. - 선언 이전에 접근하면 ReferenceError 가 발생한다. - 클래스 내부 메서드는 프로토타입에 자동으로 정의되며, 메서드 자체는 호이스팅되지 않는다.


호이스팅이 미치는 영향

  1. 코드 가독성
  2. 선언 위치와 실제 초기화 시점이 달라 가독성이 저하될 수 있다.
  3. let·const 사용으로 선언 위치와 초기화 시점을 명확히 할 수 있다.

  4. 버그 발생 가능성

  5. var와 함수 표현식에 의한 undefined·TypeError가 흔히 발생한다.
  6. TDZ에 대한 이해 부족은 ReferenceError 를 초래한다.

  7. 성능

  8. 호이스팅 자체가 큰 성능 오버헤드를 일으키지는 않지만, 불필요한 전역 변수 생성은 메모리 사용량을 증가시킬 수 있다.

호이스팅 관련 오류와 디버깅

오류 발생 원인 해결 방안
ReferenceError: Cannot access 'x' before initialization let·const TDZ 위반 선언을 사용 전에 배치하거나, 선언을 최상단으로 이동
TypeError: x is not a function 함수 표현식이 undefined 상태에서 호출 함수 선언식 사용 혹은 변수 할당 전에 호출 금지
ReferenceError: x is not defined 전역/지역 변수 미선언 변수 선언을 명시적으로 추가
SyntaxError: Identifier 'x' has already been declared 동일 스코프 내 중복 선언 (let·const) 중복 선언 제거 또는 블록 스코프 조정

디버깅 팁 - 콘솔에 console.log 로 변수 선언 전후 값을 출력해 TDZ 여부 확인. - ESLint 규칙 [no-use-before-define](/doc/%EA%B8%B0%EC%88%A0/%EA%B0%9C%EB%B0%9C%EB%8F%84%EA%B5%AC/IDE/no-use-before-define) 을 활성화해 사전 사용을 방지. - 브라우저 DevTools 의 Scope 창을 활용해 현재 스코프와 변수 상태를 시각화.


모범 사례

  1. let·const 우선 사용
  2. 블록 스코프와 TDZ를 활용해 선언 위치와 초기화를 명확히 함.
  3. 함수 선언식 대신 화살표 함수·함수 표현식 사용
  4. 선언 위치가 명확해 코드 흐름을 파악하기 쉬움.
  5. 전역 변수 최소화
  6. 전역 스코프에 변수를 선언하면 호이스팅이 복잡해지고 충돌 위험이 커짐.
  7. ESLint·Prettier 등 정적 분석 도구 활용
  8. no-use-before-define, [prefer-const](/doc/%EA%B8%B0%EC%88%A0/%EA%B0%9C%EB%B0%9C%EB%8F%84%EA%B5%AC/IDE/prefer-const) 같은 규칙으로 호이스팅 관련 버그를 사전에 차단.
  9. 코드 리뷰 시 선언 위치 확인
  10. 특히 var와 함수 표현식이 섞여 있는 경우, 선언·할당 순서를 검증.

참고 자료


본 문서는 자바스크립트 실행 컨텍스트와 호이스팅 메커니즘을 이해하고, 실무에서 발생할 수 있는 오류를 예방하기 위한 가이드라인을 제공한다.

AI 생성 콘텐츠 안내

이 문서는 AI 모델(gpt-oss-120b)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?