JavaScript Hoisting(호이스팅)

• JavaScript의 변수 생성 단계

JavaScript에서는 3단계에 걸쳐서 변수를 생성함

  1. 선언(Declaration)
    변수 객체를 생성하고 변수를 등록
    스코프가 변수 객체를 참조
  2. 초기화(Initialization)
    변수 객체 값을 위한 공간을 메모리에 할당
    이 때, 할당되는 값은 undefined
  3. 할당(Assignment)
    undefined로 초기화된 변수에 실제 값을 할당

 


• Hoisting(호이스팅)이란?

  • 코드를 실행하기 전, 변수/함수 선언을 해당 스코프의 최상단으로 끌어올려진 것 같은 현상
  • JavaScript의 독특한 특징 중 하나
  • 컴파일 단계에서 코드 실행 전, 함수와 변수 선언을 스캔하고,
    모든 함수와 변수 선언들은 스코프에 등록(메모리에 저장)

JavaScript에서는 나중에 선언되는 변수에 미리 접근 가능

console.log(value);	// undefined
var value = 'Hello';
console.log(value);	// "Hello" 출력

-> ReferenceError(선언되지 않은 변수 접근)이 발생하지 않음

    호이스팅이 일어나서 undefined로 초기화됨

 


• 변수 선언에서 호이스팅

console.log(text);	// 선언 + 초기화 된 상태 -> "undefined" 출력 
text="hello";	// 선언 + 초기화 + 할당 된 상태
var text;
console.log(text);	// "hello" 출력
  • var 키워드로 선언한 변수는 선언 단계와 초기화 단계가 한 번에 이루어짐
    -> 스코프에 변수를 등록(선언)하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화
  • 변수 선언문 이전에 변수에 접근해도 에러 발생하지 않음
console.log(text);	// Uncaught ReferenceError
let text;
  • let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 나눠서 이루어짐
    -> 스코프에 변수를 등록(선언)하지만, 초기화는 변수 선언문에 도달했을 때(코드 실행 후) 이루어짐
  • 초기화되지 않은 변수에 접근했으므로 ReferenceError가 발생
    -> 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문임
  • 스코프 시작 지점~초기화 시작 지점까지 변수를 참조할 수 없음
    -> 일시적 사각지대(Temporal Dead Zone; TDZ)

* const는 상수를 선언하는 키워드로 선언과 동시에 초기화해야 하고, 후에 다른 값을 재할당 X

 


• 함수 선언에서 호이스팅

foo1();	// 함수 선언문이라 호이스팅 일어남 -> "Hello" 출력

function foo1() {
  console.log('Hello');
}

함수가 선언되기 전에 함수를 호출가능

 

foo2();	// 함수 표현식이라 호이스팅 일어나지 않음  -> Uncaught TypeError: foo2 is not a function

var foo2 = function() {
  console.log('world');
}

함수 표현식으로 정의된 경우에는 호이스팅이 발생 X

변수 foo2는 호이스팅 되지만, 함수를 할당하는 것은 호이스팅 되지 않음

인터프리터는 변수 foo2를 함수가 아닌 일반 변수로 취급하므로 TypeError가 발생

 


• 우선순위

동일한 이름의 변수와 함수를 선언하는 경우, 우선순위가 존재함

변수 할당 > 함수 선언 > 변수 선언

fun msg() {
  console.log('msg() call!');
}

var value = 'Hello';

console.log(typeof msg);	// string

변수 할당이 함수 선언 보다 우선순위이므로 value에 'Hello'가 할당됨

function msg() {
  console.log('msg() call!');
}

var msg;

console.log(typeof msg);	// function

함수 선언이 변수 선언보다 우선순위이므로 msg에 함수가 선언됨

 


정리

  • 자바스크립트 엔진은 코드를 실행하기 전,
    실행 가능한 코드를 형상화 하고 구분하는 과정(실행 컨텍스트 형성)을 거친다.
  • 이 과정에서 모든 선언(var, let, const, function, class)이 변수 객체 메모리에 저장된다.
  • 코드 실행 전, 변수 및 함수에 대한 선언이 저장되어 있기 때문에 선언문보다 먼저 호출해도 동작할 수 있다.
  • 선언이 마치 파일의 최상단으로 끌어올려진 것처럼 보이는데, 이것이 호이스팅이다.

'JavaScript' 카테고리의 다른 글

JavaScript 동작원리  (0) 2023.05.27
JavaScript DOM  (0) 2023.05.16
JavaScript 비동기 처리 방법(Promise, async, await)  (0) 2023.05.03
JavaScript 동기/비동기(동작 원리)  (0) 2023.05.03
JavaScript란?  (0) 2023.05.03