💻 Frontend

JavaScript hoisting이란?

category
💻 Frontend
 

호이스팅의 개념

함수 안에 있는 선언들을 모두 최상단에 끌어올려 선언하는 것처럼 동작하는 현상을 말한다. MDN에서는 아래와 같이 정의한다.
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미
 

변수 호이스팅

var로 선언한 변수의 경우 호이스팅 시 undefined 로 변수를 초기화 한다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않는다.
console.log(foo); // ① undefined var foo = 123; console.log(foo); // ② 123
console.log(bar); // ReferenceError let bar = 123; console.log(bar);
foo를 선언해주기 전에 콘솔에 찍었는데 에러가 나지 않고 왜 undefined가 찍혔을까? 그 이유는 바로 호이스팅 현상이 일어났기 때문이다. 변수가 어떻게 생성되며 호이스팅은 어떻게 이루어지는지 좀 더 자세히 살펴보자. 변수는 3단계에 걸쳐 생성된다.
선언 단계 변수 객체(Variable Object)에 변수를 등록한다. 이 변수 객체는 스코프가 참조하는 대상이 된다. 초기화 단계 변수 객체(Variable Object)에 등록된 변수를 메모리에 할당한다. 이 단계에서 변수는 undefined로 초기화된다. 할당 단계 undefined로 초기화된 변수에 실제값을 할당한다.
var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 즉, 스코프에 변수가 등록되고 변수는 메모리에 공간을 확보한 후 undefined로 초기화된다. 따라서 변수 선언문 이전에 변수에 접근하여도 변수 객체에 변수가 존재하기 때문에 에러가 발생하지 않는다. 다만 undefined를 반환할 뿐이다. 이러한 현상을 변수 호이스팅이라 한다. 이후 변수 할당문 foo = 123; 에 도달하면 비로소 값의 할당이 이루어진다.
호이스팅 관점으로 한번 더 예제를 봐보자.
var foo; console.log(foo); // ① undefined var foo = 123; console.log(foo); // ② 123
notion image
①을 실행되기 이전에 var foo = 123;이 호이스팅되어 최상단에 var foo;가 옮겨진다. 실제로 변수 선언이 코드 레벨로 옮겨진 것은 아니고 변수 객체(Variable object)에 등록되고 undefined로 초기화된 것이다. 하지만 let키워드로 변수를 선언하면 에러가 뜬다. let 키워는 var 키워드와 다른점이 무엇일까?
let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 스코프에 변수를 등록하지만 초기화 단계는 변수 선언문에 도달했을 대 이루어진다. 초기화 이전에 변수에 접근하려고하면 참조에러가 발생한다. 이는 변수가 아직 초기화되지 않았기 때문이다. 변수를 위한 메모리 공간이 아직 확보되지 않았다는 것이다. 따라서 스코프의 시작지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다. 스코프의 시작 지점부터 초기화 시작지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.
// 스코프의 선두에서 선언 단계가 실행된다. // 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다. // 따라서 변수 선언문 이전에 변수를 참조할 수 없다. console.log(foo); // ReferenceError: ㄴCannot access 'foo' before initialization let foo; // 변수 선언문에서 초기화 단계가 실행된다. console.log(foo); // undefined foo = 1; // 할당문에서 할당 단계가 실행된다. console.log(foo); // 1
notion image
 
 

마무리

호이스팅이란?
코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상
 
변수 호이스팅
모든 선언에는 호이스팅이 일어난다.
var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다.
let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
let , const 은 에러 발생때문에 호이스팅이 일어나지 않는 것처럼 보이지만, 에러가 발생하는 것은 호이스팅이 일어났기 때문이다.
 
변수의 생성단계
  1. 선언 단계
    1. 변수 객체에 등록
  1. 초기화 단계
    1. 변수를 위한 공간을 메모리에 확보. 이 단계에서 변수는 undefined로 초기화 됨.
  1. 할당 단계
    1. 실제 값을 할당.
 
일시적 사각지대란?
스코프의 시작 지점부터 초기화 시작지점까지의 구간
let 키워드로 선언된 변수를 선언문 이전에 참조하면 참조에러가 발생한다. 이유는 일시적 사각지대에 빠지기 때문이다.
 

Reference