본문 바로가기
javascript

hoisting

by rami_ 2024. 3. 26.

자바스크립트에서 호이스팅은 중요한 개념이다.


자바스크립트 파일이나 스크립트를 실행하게되면 v8엔진으로 해석하게되는데 이때 인터프리팅 과정과 컴파일 과정이 이루어지게 된다(이 두 과정을 거치는걸 JIT, Just-In-Time 이라고하며 여러번 코드가 실행되면서 이전에 컴파일 결과를 재사용한다).

호이스팅은 v8엔진이 코드를 실행하기 전에 선언을 해당 스코프의 최상단으로 끌어올리는 것이다.

오늘은 호이스팅과 관련된 문제들을 살펴보며 호이스팅에 대해 깊이 생각해보려고한다.

1. var + 함수선언식

console.log(myFunc);
var myFunc = 'Hello, World!';

function myFunc() { 
  console.log('Function called');
}

myFunc();

 

자바스크립트 코드나 파일을 해석을 위해 v8엔진 위로 올림.
v8엔진은 인터프리팅 과정과 컴파일 과정이 있는데 컴파일 과정에서 호이스팅이 일어난다.
여기서는 변수 myFunc와 함수선언문 myFunc가 호이스팅되는데 이때 함수선언문이 우선순위가 높으므로 처음 console.log에는 함수 myFunc의 함수 자체가 찍힌다.

이후 변수 myFunc에 'Hello, World!' 스트링을 할당하여 초기화 합니다. 이후 myFunc를 실행시키는데 이때 myFunc는 함수가 아니라 문자열이 할당된 변수이기 때문에 실행되지 않고 TypeError가 난다.

 

 

2. var + 즉시 실행 함수

var name = "Baggins";

(function () {
    console.log("Original name was " + name);

    var name = "Underhill";

    console.log("New name is " + name);
})();

 

자바스크립트 코드가 실행되기 전 코드 평가 단계에서 호이스팅이 일어나는데 변수 name은 호이스팅 되어 undefined이며(아직 초기화되지 않았기 때문에) 이후 코드가 실행되며 name에 문자열을 할당하여 초기화하고 즉시실행함수가 실행된다. 

즉시실행함수는 함수블럭 안에 존재하고  var name은 함수 scope를 가지고 있고 name이 scope 최상단으로 호이스팅되는데 이때 undefined이다. 이후 초기화 전에 콘솔이 있으므로 첫번째 콘솔에 찍히는건 Original name was undefined 이다. 이후 name에 문자열을 할당하여 초기화하고 이후 콘솔에는 New name is Underhill이 찍히게 된다.

 

 

3. var + 함수선언식

console.log(foo);

var foo = 5;

console.log(foo);

function foo() {
  console.log("bar");
}

console.log(foo);

 

자바스크립트 호이스팅이 일어나게 되는데 변수 foo와 함수 foo가 호이스팅 되며 함수선언문이 우선순위를 가지며 첫번째 콘솔로그는 함수선언문 foo의 참조(함수 자체 출력)이다. 이후 변수 foo에 5를 할당하여 초기화했으며 두번째 콘솔로그에는 5가 찍히게 된다. 이후 foo에게 재할당이 이루어지지 않았으므로 세번째 콘솔로그에도 5가 찍히게 된다.

 

 

4. var + 함수표현식

console.log(foo);

var foo = 5;

console.log(foo);

const foo = () =>  {
  console.log("bar");
}

console.log(foo);

 

 

자바스크립트 엔진이 스크립트를 처음 평가할 때 동일한 스코프 내에 같은 이름의 변수를 사용하려고 시도한 것을 감지하고 syntaxError를 내보내고 더이상 실행되지 않는다.

 

 

'javascript' 카테고리의 다른 글

closure  (0) 2024.03.27
scope  (1) 2024.03.26
자바스크립트의 비동기처리  (0) 2024.03.18
자바스크립트의 은닉화 그리고 모듈  (3) 2024.03.12
rollup  (0) 2024.03.10