[Javascript] 호이스팅이 뭘까요?

허북이_·2023년 1월 5일
0

JS

목록 보기
19/19
post-thumbnail

호이스팅(hoisting)

: Hoist(:끌어 올리다) 에서 비롯된 용어로 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것 뜻합니다.

인터프리터
프로그래밍 언어의 소스 코드를 바로 실행하는 컴퓨터 프로그램 또는 환경을 말한다.

var 키워드로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 letconst로 선언한 변수의 경우는 초기화하지 않습니다.

JavaScript는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당합니다. (= 호이스팅합니다) 덕분에 함수를 호출하는 코드를 함수 선언보다 앞서 배치할 수 있습니다.

함수 호이스팅

함수 호이스팅은 내부적으로 다른 무엇보다 가장 먼저 이루어집니다. 그리고 함수 호이스팅은 함수 선언문에만 해당됩니다.

함수의 선언문은 식별자가 변수 객체에 수집될 때 부가적으로 해당 함수 참조에 대한 초기화까지 자동으로 이루어집니다. 이로 인하여 선언된 함수는 상단에서 참조, 호출이 가능합니다.

함수 표현식은?
함수 표현식은 결국 함수를 변수에 할당하는 것이므로 변수 호이스팅의 사례로 볼 수 있습니다.

변수 호이스팅

변수는 프로그램 내에서 크게 세 가지 단계를 거칩니다.

  1. 선언: 파싱 과정에서 변수 객체가 변수에 대한 식별자들을 수집합니다.
  2. 초기화: 식별자에 메모리를 할당하고 초기 상태로undefined를 부여합니다.
  3. 할당: 변수 안에 직접 값을 넘겨 줍니다.

함수 호이스팅에서 그랬듯이 변수 또한 선언과 초기화를 해주어야만 값의 참조 및 할당이 가능합니다. 다만 변수 선언 방식(키워드)에 따라 선언, 초기화의 시점이 달라질 가능성이 있습니다.

  • var: 호이스팅이 발생하면 선언과 초기화가 거의 동시에 이루어집니다. 해당 변수에 대한 메모리가 실행 시점의 스코프 최상단에 존재하기 때문에 선언부 위치에 상관없이 참조, 할당이 가능합니다.

  • let, const: 호이스팅이 발생하면 선언만 이루어지고 실행 지점에서 실질적인 선언부를 만날 때까지 초기화가 이루어지지 않습니다. 이 간극만큼 해당 변수에 대한 메모리가 존재하지 않기에 선언부 상단에서 참조, 할당이 불가능합니다.

let, const가 동작하는 과정에서 스코프의 진입지점과 해당 식별자의 실질적 선언부 사이를 일시적 사각지대, TDZ(Temporal Dead Zone) 라고 합니다. 이 시점에서 변수는 존재하지만, 초기화가 이루어지지 않았습니다.

예제

// 1번 코드
function myName(name) {
  console.log("제 이름은 " + name + "입니다");
}

myName("허정우");

// 2번 코드
myName("허정우");

function myName(name) {
  console.log("제 이름은 " + name + "입니다");
}

// 결과: 제 이름은 허정우입니다

1번 코드와 2번 코드는 함수 호출과 선언의 시점이 다르지만 같은 방식으로 동작하는 것을 볼 수 있습니다.

함수 호출이 함수 자체보다 앞서 존재하여도 코드가 동작합니다. 이것이 JavaScript에서 실행 맥락이 동작하는 방식입니다.

호이스팅은 다른 자료형과 변수에도 작동합니다. 변수를 선언하기 전에 먼저 초기화하고 사용할 수 있는 것입니다.

대상

JavaScript는 초기화를 제외한 선언만 호이스팅합니다. 변수를먼저 사용하고 그 후에 선언 및 초기화가 나타나면, 사용하는 시점의 변수는 기본 초기화 상태입니다.

console.log(num); 출력
var num; // 선언
num = 10; // 초기화
// 호이스팅한 var선언으로 인해 undefined 
console.log(num);
num = 10; // 초기화
// 선언이 없고 초기화만 존재, 호이스팅 X
// 변수 읽기 시도 -> ReferenceError 예외 발생

Reference.
MDN
호이스팅의 오해와 진실

profile
인간 거북이 허북이

0개의 댓글