본문 바로가기

Study/JavaScript

Hoisting

+) scope, execution context 챕터와 함께✍️

Hoisting

hoist란 "끌어올리다"의 의미를 갖는 단어이다. JS에서 hoist 역시 무언가를 끌어올리는 것과 관련이 있다.

JS엔진의 interpreter는 우리가 작성한 프로그램이 실행되면, 소스 코드를 컴퓨터가 이해할 수 있는 언어로 한줄 씩 번역하는 역할을 하는데, 이 작업을 시작하기 전에 hoisting이 일어난다.

 

hoisting이란, 함수, 변수, 클래스의 선언(declaration, not initialization)이 어디에 작성되어 있든지 간에, 해당 선언문을 이들이 작성된 scope의 최상단에 있는 것처럼 끌어올리는 것을 말한다. 

 

이제 함수와 변수, 클래스의 경우를 나누어 hoisting에 대해 살펴보자. 

1. Function 

함수 선언은 hoisting 된다. 이는 곧 우리가 코드의 어느 곳에서 함수 선언을 작성하든지 간에, 해당 컨텍스트 안의 최상단에 작성된 것과 같이 코드를 실행하게 된다는 의미이다. 즉, 우리는 함수가 선언되기 이전에도 함수를 호출할 수 있다.

 

print(); // 콘솔에 'hello'를 정상적으로 출력

function print() {
  console.log('hello');
}

 

+) 함수 표현식은 함수가 아니라 변수로서 hoisting 된다. 

2. Variables & Class 

변수와 클래스 선언 역시 동일하게 hoisting의 대상이다. 하지만 함수 선언의 경우와 달리 주의해야 할 사항이 있는데,  바로 declaration과 initialization의 구분이다.

 

console.log(myAge) // 무슨 일이 일어날까요? 

let myAge; // Declaration 
my Age = 23; // Initialization

class Cat {} // Declaration 
class Cat { // Initialization
  constructor(name) {
    this.name = name;
    }
}

 

앞서 우리는 선언(declaration, not initialization)만 hoisting 된다는 것을 살펴보았다.

 

위의 코드가 실행되면 global execution context에 myAge라는 변수가 등록된다. 그러나 이 변수가 identifier로서 존재한다는 사실만 알고 있을 뿐이지, 실제 변수에 어떤 값이 할당되었는지는 myAge = 23; 코드를 실행할 때 알게 된다. 

 

즉 콘솔에 myAge를 출력하는 코드를 실행하는 시점에서 myAge라는 변수는 알고있으나(declaration), 이 변수에 어떤 값이 할당되어있는지(initialization)는 모르기 때문에 "not initialized" 에러를 던지고, app이 crash된다. 

 

+) 이 때 var hoisting의 경우에는 동일한 상황에서 에러를 던지는 것이 아니라, "undefined"을 호출한다. var로 선언된 변수는 hoisting 되면서 그 값이 undefined으로 초기화되기 때문이다. 

 

ex) 

 

var a = 1;
function outer() {
  function inner() {
    console.log(a); // 1.undefined
    console.log(b); // 2. not initialized error
    var a = 3;
    const b = 5; 
  }
  inner();
  console.log(a); // 3. 1
}
outer();
console.log(a); // 4. 1

 

'Study > JavaScript' 카테고리의 다른 글

shallow vs. deep copy  (0) 2022.08.08
Modern Syntax | Params, Spread, De-structuring  (0) 2022.05.26
Var  (0) 2022.05.25
Request & Response | API, JSON, fetch...  (0) 2022.04.17
This  (0) 2022.04.05