Skip to main content

Command Palette

Search for a command to run...

자바스크립트의 호이스팅

자바스크립트의 호이스팅에 대해서 오개념 유무를 점검하고 배운 내용을 정리했습니다.

Updated
3 min read
자바스크립트의 호이스팅

호이스팅

자바스크립트의 모든 변수는 호이스팅된다. 호이스팅이란 변수, 함수, 클래스 선언을 스코프의 최상단으로 위치시키는 것을 의미한다.

  • 변수를 var로 선언할 때는 선언함과 동시에 undefined라는 값으로 초기화된다.

  • let 또는 const로 선언할 때에는 초기화가 되지 않기 때문에 ReferenceError 에러가 발생한다.

    • 만약 변수가 호이스팅되지 않는다면 선언되지 않은 변수입니다.라는 식의 에러가 발생했을 것이다.
  • 함수 선언문도 호이스팅된다.

  • 함수 표현식에서는 함수의 이름만 호이스팅되고 함수 자체는 정의하기 전에는 호출할 수 없다. 옵셔널 체이닝을 사용해서 에러가 발생하는 것을 방지할 수 있다.

    • 호이스팅된 함수의 이름을 typeof로 타입을 확인해보면 undefined라는 값을 얻을 수 있다.
console.log(num); // ReferenceError
let num = 100;
console.log(num); // 100
console.log(typeof introduce === "undefined");
introduce("Jane Doe"); // introduce is not a function
introduce?.("Jane Doe");
var introduce = function (name) {
  const message = `Hello, I am ${name}`;
  console.log(message);

  return message;
};
introduce("John Doe");

예시

예전에는 호이스팅에 대해서 깊게 관심가지지 않았고 let, 또는 const 변수는 호이스팅이 되지 않는 것으로 알고 있었다. 프로젝트를 진행하면서 변수 선언 및 초기화 관련 에러를 가끔씩 마주치게 되었고 호이스팅에 대해서 다시 정리하게 되었다.

다음과 같은 상황에서도 ReferenceError가 발생한다.

let num = 10;
function increment() {
  num++;

  console.log(num);
  let num = num + 100;
  console.log(num);
}
increment();

increment 함수에서 num++은 함수 바깥 스코프에 선언된 변수의 값을 1 증가시키는 것으로 예상했었다.

함수 내부에서 num이 선언되었기 때문에 변수는 함수 최상단에 호이스팅되고, num++으로 값을 증가시키려고 하면 아직 초기화가 되지 않았기 때문에 역시 ReferenceError가 발생하는 것이다.

에러가 발생하지 않게 하려면 함수 최상단에서 변수 초기화까지 완료시키거나, 변수 선언문을 제거하여 바깥 스코프의 변수를 참조시킬 수 있다.

let _num = 10;
function increment() {
  let num = _num;
  num++;

  console.log(num);
  num = num + 100;
  console.log(num);
}
increment();
let num = 10;
function increment() {
  num++;

  console.log(num);
  num = num + 100;
  console.log(num);
}
increment();

TDZ

자바스크립트의 변수가 호이스팅되기 때문에 TDZ라는 개념이 존재한다.

TDZ(Temporal Dead Zone)는 스코프의 시작 지점에서 변수가 초기화되기까지의 구간을 의미하며, 이 구간에서는 변수에 접근할 수 없다.

렉시컬 스코프가 함수가 작성된 위치에 따라 결정되는 반면, TDZ는 각 코드가 작성된 위치보다는 실행 시점에 따라 결정된다.

  • john 변수는 함수 선언문 다음에 선언 및 초기화되도록 작성되어 있다.

  • 호이스팅에 의해 변수 선언문이 최상단에 위치하게 된다. 따라서 greeting 함수 스코프에서는 선언된 john 변수를 참조할 수 있다.

  • greeting 함수가 호출되는 시점에는 변수가 초기화까지 되었기 때문에 에러가 발생하지 않는다.

function init() {
  const greeting = () => {
    const message = `Hello, I am ${john.name}`;
    console.log(message);
    return message;
  };

  const john = {
    name: "John Doe",
    age: 30,
    region: "US",
  };
  greeting();
}
init();

상속되는 클래스의 경우 constructor 함수에서 super 함수가 호출되기 전까지는 this에 접근할 수 없다. super를 통해 원본 클래스에서 생성자를 호출하여 퍼블릭 속성, 메소드를 this에 바인딩하고 나서 상속 클래스 생성자에서 this에 접근 및 변경할 수 있다.

class Person {
  public name: string;
  public age: number;
  public region: string;
  constructor(name: string, age: number, region: string) {
    this.name = name;
    this.age = age;
    this.region = region;
  }
}

class Employee extends Person {
  public company: string;
  public department: string;
  constructor(
    name: string,
    age: number,
    region: string,
    company: string,
    department: string
  ) {
    this.company = company; // ReferenceError
    this.department = department; // ReferenceError
    super(name, age, region);
  }
}

class Employee extends Person {
  public company: string;
  public department: string;
  constructor(
    name: string,
    age: number,
    region: string,
    company: string,
    department: string
  ) {
    super(name, age, region);
    this.company = company;
    this.department = department;
  }
}

More from this blog

AI 에이전트에서 작업 맥락을 관리하기 위해 사용한 방법

AI 에이전트의 불편함 Codex CLI와 같은 AI 코딩 에이전트를 통해서 프로젝트 개발 속도를 높일 수 있다. 그리고 혼자 작업했을 때는 놓칠 수 있는 부분도 발생할 수 있는데 AI 에이전트를 통해 보완할 수 있었다. 컴포넌트에 대해서 접근성 태그 작성 API 호출하는 비동기 코드 작성할 때 에러 처리 그리고 AI 에이전트를 잘 활용하면 불가능하

Mar 8, 202610 min read

지시사항을 분할하여 Codex로 효율적인 작업하기

이슈 Codex와 같은 AI 기반 코드 에이전트는 출력 토큰의 수가 제한되어 있다. 그래서 다양한 작업을 하나의 프롬프트에 전부 몰아서 작성하면 원하는 결과가 나오지 않을 수 있다. Codex와 같은 LLM 기반 서비스는 출력 토큰 수를 초과하게 되면 일부 단계가 누락되거나 특정 요소를 과하게 요약할 수 있고 이는 전체적인 답변 퀄리티를 낮출 수 있기 때문이다. 그래서 다양한 AI 공식문서는 특정 작업을 더 작은 단위로 분할하는 방식을 강조한다...

Nov 3, 20255 min read

Key를 활용하여 컴포넌트 상태를 초기화하기

개요 컴포넌트의 상태가 업데이트되어도 컴포넌트 내부에 배치된 컴포넌트의 상태는 그대로 유지되는 경우가 있었다. 예전에는 Props 전달 및 내부에서 useEffect를 통해서 상태를 초기 상태로 업데이트하도록 했는데 useEffect를 남용하게 되면 상태 변화 추적이 어려워지는 문제가 있었다. 그런데 useEffect 외에도 Key를 통해서 컴포넌트 상태를 초기화할 수 있다는 사실을 알게 되었다. 리스트 렌더링 React 프론트엔드에서 목록 형...

Sep 21, 20253 min read

내가 AGENTS.md를 작성하는 방법

Codex CLI 요즘 프로젝트 개발에 Codex CLI를 활용하는 이유는 다음과 같다. 특정 프로젝트를 작업할 때 Claude Code는 종종 사용량을 초과한 것과 다르게 Codex CLI는 ChatGPT Plus 요금제만으로도 토큰 사용량 초과 걱정 없이 충분하게 활용할 수 있었다. 타 CLI 기반 AI 개발 도구에 비해서 요구사항을 더 정확하게 구현하고 꼭 필요한 작업만 진행하기 때문에 코드를 검토하는 시간을 줄일 수 있다. 반복적인 코드...

Sep 21, 20254 min read
N

Nowon Lee

22 posts