[Javascript] Hoisting

yes·2022년 3월 28일
0

Javascript

목록 보기
5/13
post-thumbnail

Hoisting이란 무엇인지 같이 맛보도록 하자😋

🗡hoisintg 정의

변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 말한다.

hoisting을 이해하려면 변수 선언이 될 때 발생하는 과정을 알아야한다.
간단하게 이해할 수 있으니까 한 번 알아보고 넘어가자.

🔍 변수 선언 과정 살펴보기

자바스크립트 엔진은 변수 선언을 다음과 같은 2단계에 거쳐 수행한다.
1. 선언 단계 : 변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다.
2. 초기화 단계 : 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다.

이제 예제를 통해 같이 살펴보도록 하자.

EX)

console.log(score); // undefined
var score; // 변수 선언문

이 코드를 보고 우리는 자바스크립트 코드는 한 줄씩 순차적으로 실행되니까 console.log(score); 실행될 때 참조 에러가 발생할 것으로 예상할 수 있다.
하지만, 참조 에러가 발생하지 않고 undefined가 출력된다.

🧐 Why??
변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.

자바스크립트 엔진은 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행한다. 그리고 이 과정이 끝나면 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 춘사척으로 실행한다.
즉, 자바스크립트 엔진은 변수 선언이 소스코드의 어디에 있든 상관없이 다른 코드보다 먼저 실행한다.

🎯 결론
따라서, 변수 선언문인 var score;가 먼저 실행되고 console.log(score);가 실행되기 때문에 참조 에러가 발생하지 않고 undefinde가 출력되게 된다.

함수까지 잘 이해하고 있다면, 마지막 함수 hoisting까지 맛보고 가길 바란다.

함수 hoisitng

// 함수 참조
console.dir(add); // ƒ add(x, y)
console.dir(sub); // undefined

// 함수 호출
console.log(add(2, 5)); // 7
console.log(sub(2, 5)); // TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y;
}

// 함수 표현식
var sub = function (x, y) {
  return x - y;
};

함수 선언문과 함수 표현식의 차이를 알고 가야하는데 이 내용은 함수파트에 따로 정리해보겠다.

위의 코드를 예제로 우선 함수 hoisting에 대해서 살펴보자.

결론부터 말하자면, 함수 선언문은 함수 hoisting이 발생하고 함수 표현식은 변수 hoisting만 발생한다. 왜냐하면 함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르기 때문이다.

  • 함수 선언문
    모든 선언문과 마찬가지로 함수 선언문도 런타임 이전에 먼저 실행된다. 다시 말해, 런타임 이전에 함수 객체가 먼저 생성된다. 그리고 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당한다. 따라서 함수 선언문 이전에 함수를 참조할 수 있으며 호출할 수도 있다. 이것을 함수 hoisting이라고 부른는 것이다.
    주의) 함수 호이스팅과 변수 호이스팅은 차이가 존재한다. var 키워드로 선언한 변수는 undefined로 초기화되고, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다. 따라서 var 키워드를 사용한 변수 선언문 이전에 변수를 참조하면 변수 호이스팅에 의해 undefined로 평가되지만 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호출하면 함수 호이스팅에 의해 호출이 가능하다.

  • 함수 표현식
    함수 표현식은 변수에 할당되는 값이 함수 리터럴인 문이다. 따라서 변수 선언은 런타임 이전에 실행되어 undefined로 초기화되지만 변수 할당문의 값은 할당문이 실행되는 시점, 즉 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.
    결론적으로 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아닌 변수 호이스팅이 발생하는 것이다.

참고)
javascirpt deep dive book
https://jiyong1.github.io/posts/01-re-assignment/

0개의 댓글