# 호이스팅

컴파일 시간동안 자바스크립트는 (function, var, let, const, class)의 값을 제외한 선언부를 메모리에 저장한다

# 컴파일 🔗

스터디-신정웅님의 JS컴파일

  1. 토큰화(스캐닝, 어휘분석, Lexical Analysis) :
    • 소스코드를 정규문법에 따라 토큰으로 분류한다.
    • 어휘항목(lexeme) - 의미있는 조각
      • 변수, 함수의 선언부
    • 어휘분석기는 소스 코드에서 어휘항목을 검출하여 토큰을 생성한다.
    • 토큰
      • 토큰 이름과 속성값으로 구성되는 데이터 쌍.
      • identifier-variable
        • identifier : 변수/함수의 이름
        • variable : 타입
         LexicalEnvironment = {
           myVar: <value>,
           myFunc: <func>
         }
      
      1
      2
      3
      4
  2. 구문화 : 토큰들을 트리로 만든다.

스캔 된 변수와 함수의 선언부들은 Lexical Environment(자바스크립트의 자료구조 메모리상)에 추가된다.

  • 메모리에 존재하는 변수와 함수는 실제 선언 이전에 사용될 수 있다.

# 호이스팅의 정의

‘Lexical Environment 가 형성될 때 함께 생성됨’

  • ‘undefined 할당’과 및 의 ‘LexicalBinding 이 평가되기 전까지는 접근 불가’ 부분은 hoisting 과는 별도로 분리하여 논해야 한다.
let a = 1;
{
  console.log(a);  // Uncaught ReferenceError: a is not defined
  let a = 2;
}
1
2
3
4
5

만약 let a = 2 의 선언부가 호이스팅이 되지 않았다면 '1' 이 출력이 될 것이다.

# 함수 선언부의 호이스팅

함수의 선언부가 컴파일 단계에서 메모리에 추가가 된다. 함수 선언 시점 이전에, 함수에 접근 가능

helloWorld();

function helloWorld() {
  console.log('hello world');
}
1
2
3
4
5

# 함수 표현식의 호이스팅

함수 표현식은 호이스팅 되지 않는다. 자바스크립트는 오직 선언만 호이스팅 한다. 변수처럼 취급된다.

helloWorld();

var helloWorld = function () {
  // ...
}
1
2
3
4
5

# 변수의 호이스팅

# var 호이스팅 된 변수

Lexical Environment 에 추가되면서 undefined 로 초기화 된다.

  • 함수 스코프에 제한된다.

# let 변수와 const 변수의 호이스팅

  • 선언전, Lexical Environment 에서는 uninitialized 로 초기화됨
  • Temporal Dead Zone : 변수의 선언과 변수의 초기화 사이의 변수에 접근할 수 없는 지점.
  • 실제 할당 전에 실행만 되지 않는다면 참조 가능
function foo() {
  console.log(a)
}
let a = 20;
foo();
1
2
3
4
5

# Temporal Dead Zone 이 생기는 이유

let, const 는 Lexical Environment 에 추가되고, 생성될때(자세한 바인딩시점은 잘모름) ReferenceError 가 바인딩 된다.

  • ReferenceError 프로그래밍적 오류를 포착하기 위한 역할을 한다.

# 클래스의 호이스팅

  • 선언전, Lexical Environment 에서는 uninitialized 로 초기화됨

# 클래스 표현식의 호이스팅

함수 표현식과 마찬가지로 호이스팅 되지 않는다.

# Reference