[JavaScript] 호이스팅

2022. 11. 5. 19:28·프로그래밍 언어/JavaScript

호이스팅이란?

일반명사) 끌어 올리기

고유명사) 선언한 위치와 상관없이 함수, 변수의 선언부를 인접한 스코프의 최상단으로 끌어올려 스코프 내 어디서든 해당 식별자를 관측할 수 있는 현상

호이스팅은 어떻게 발생하는가?

하지만 자바스크립트 엔진은 실제로 코드를 실행하는 시점에 함수, 변수의 선언부를 인접한 스코프의 최상단으로 끌어올릴 만한 능력이 없다. 단지 코드 실행 전에 어떤 과정을 거쳐서 변수, 함수에 대한 전체적인 정보를 미리 알고 있을 뿐이다.

여기서 말하는 어떤 과정이란

참고) 자바스크립트는 코드 실행 전 따로 컴파일 과정을 거친다.

컴파일 : 사람이 이해하는 언어로 이루어진 코드를 컴퓨터가 이해할 수 있도록 쪼개고, 체계적인 구조로 재가공하여 전체를 분석하는 일련의 과정

자바스크립트 엔진은 코드 실행 전 모든 스코프를 탐색하며 각 스코프의 변수 객체에 여러 식별자를 수집한다.

즉 코드 실행 시점으로 넘어가기 전에 선언된 식별자에 대한 정보를 이미 알고 있기 때문에 스코프의 어느 지점이든 관련된 함수/변수를 참조할 수 있는 것이다.

호이스팅 규칙

호이스팅은 크게 함수 호이스팅과 변수 호이스팅으로 나뉜다.

  • 선언된 함수는 스코프의 어느 지점이든 참조, 호출이 가능하다.
  • var 로 선언된 변수는 스코프의 어느 지점이든 참조, 할당이 가능하다.
  • let, const 로 선언된 변수는 스코프의 어느 지점이든 참조, 할당이 불가능하다.

1. 함수 호이스팅

함수의 선언문만 호이스팅이 일어난다.

함수의 선언문은 식별자가 인접한 스코프의 변수 객체에 수집될 때 부가적으로 해당 함수의 참조에 대한 초기화까지 자동으로 이루어진다.

이 덕분에 함수를 호출하는 코드를 함수 선언보다 앞서 배치할 수 있다.

 

예시) 함수 선언문 이후에 함수 호출 (일반적인 코드 작성 순서)

function dogName(name) {
    console.log("제 강아지의 이름은 " + name + "입니다.");
}

dogName("멍멍이");

/*
결과: "제 강아지의 이름은 멍멍이입니다."
*/

예시) 함수 선언문 이전에 함수 호출 (함수 호이스팅 발생)

dogName("멍멍이");

function dogName(name) {
    console.log("제 강아지의 이름은 " + name + "입니다.");
}

/*
결과: "제 강아지의 이름은 멍멍이입니다."
*/

 

함수 표현식은 호이스팅이 일어나지 않는다.

함수 표현식은 어떤 변수에 함수를 할당하는 것처럼 보여 변수 호이스팅의 사례로 보여질 수 있다.

예시)

var value = 'value';
var func = function () { }

 

2. 변수 호이스팅

변수는 어떻게 선언했는지에 따라 선언, 초기화 시점이 달라질 수 있다.

 

var 는 호이스팅이 발생하면 선언과 초기화가 거의 동시에 이루어진다. 실행 시점의 스코프 최상단에서 해당 변수에 대한 메모리가 살아 있기 때문에 선언부 위치에 상관없이 참조, 할당이 가능하다.

let, const 는 호이스팅이 발생하면 선언만 이루어지고 실행 시점에서 실질적인 선언부를 만날 때까지 초기화는 이루어지지 않는다.

이 간극만큼 해당 변수에 대한 메모리는 존재하지 않기 때문에 선언부 상단에서 참조, 할당이 불가능하다.

일시적 사각지대(TDZ(Temporal Dead Zone)) : let, const 가 동작하는 과정에서 스코프의 진입 지점과 해당 식별자의 실질적 선언부 사이, 여기서 식별자는 존재하지만 초기화되어 있지 않다.

변수 호이스팅 예시

예시) var 호이스팅

console.log(num); // 호이스팅한 var 선언으로 인해 undefined 출력
var num; // 선언
num = 6; // 초기화

예시) 선언 없이(호이스팅 X) 초기화만 존재

console.log(num); // ReferenceError: num is not defined
num = 6; // 초기화

예시) var 호이스팅

// 예제 1
// b 만 호이스팅 대상

a = 2; // a 초기화. a 를 선언하지 않은 경우 선언. 그러나 var 가 없으므로 호이스팅이 발생하지 않음.
console.log(a + " " + b); // '2 undefined'
// JavaScript 는 선언만 호이스팅하므로, 윗줄의 b 는 undefined
var b = 3; // b 를 선언하고 초기화

예시) let, const 호이스팅

{
    /*
     Temporal Dead Zone of a
     a 는 이 구간에서 참조할 수 없다.
     console.log(a); // Reference Error
    */
    let a;
}

예시) let, const 호이스팅

console.log(a); // ReferenceError: Cannot access 'a' before initialization
// let 호이스팅이 일어나 전역 스코프의 변수 객체에 식별자는 수집됐으나 초기화가 이루어지지 않음.
let a;

참조

https://tecoble.techcourse.co.kr/post/2021-04-25-hoisting/

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

 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

JavaScript 의 동작방식  (0) 2022.11.12
[JavaScript] 반복문  (0) 2022.11.05
[JavaScript] 실행 컨텍스트  (0) 2022.11.05
[JavaScript] 스코프(Scope)  (0) 2022.11.05
[JavaScript] 런타임 메모리 구조  (0) 2022.11.05
'프로그래밍 언어/JavaScript' 카테고리의 다른 글
  • JavaScript 의 동작방식
  • [JavaScript] 반복문
  • [JavaScript] 실행 컨텍스트
  • [JavaScript] 스코프(Scope)
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (99)
      • k8s (1)
      • AWS (1)
      • 리눅스 (3)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스택
    mysql
    쿠버네티스
    typeorm
    nestjs
    javascript
    Kubectl
    Python
    Til
    생활코딩
    배열
    django
    모듈
    iterable
    자바스크립트
    컨테이너
    코딩테스트
    redis
    IP 주소
    도커
    Kubernetes
    Docker
    조인
    FastAPI
    네트워크
    typescript
    기초
    레벨2
    프로그래머스
    리눅스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
[JavaScript] 호이스팅
상단으로

티스토리툴바