호이스팅

이재홍·2022년 12월 28일
0

JavaScript

목록 보기
6/10
post-thumbnail

✅호이스팅이란 무엇일까?

  • 어디에 선언이 되어 있나 상관없이 최상단 위로 끌어 올려주는 것이다 ?? (Hoist:끌어 올리다))

    • 함수와 변수는 코드를 실행하기 전에 실행 컨텍스트를 위해 메모리에 저장된다. 이것을 호이스팅 이라고 한다.
  • 변수, 함수의 선언부가 위치한 인접 스코프의 시작 지점에서 해당 식별자의 관측이 가능한 현상

✅MDN

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다.
var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.

호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다.
따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다.
다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.

호이스팅은 (let과 const를 포함한) ECMAScript® 2015 언어 명세 이전의 표준 명세에는 나타나지 않았습니다.

✅ 호이스팅의 규칙

호이스팅은 크게 함수 호이스팅과 변수 호이스팅으로 나뉜다.
이 3가지 규칙을 숙지하고 가보자.

  • 선언된 함수는 상단에서 참조, 호출이 가능하다.
  • 선언된 var 는 상단에서 참조, 할당이 가능하다.
  • 선언된 let , const 는 상단에서 참조, 할당이 불가능하다

✅ 함수의 선언

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

calculateAge(1999); // 함수 선언 전에 함수를 호출 -> hoisting 이 되어 잘 작동한다.

function calculateAge(year) {
  // 함수 선언.
  console.log(2020 - year);
}

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

//retirement(1990); // 작동하지 않는다

var retirement = function (year) {
  // 함수의 선언 방식이 아니기 떄문에 hoisting 되지 않는다. (only work on function declaration)
  console.log(65 - (2020 - year));
};

함수 표현식은 결국 어떠한 변수로 함수를 할당하는 모양새여서 이것 또한 변수 호이스팅 사례로 볼 수 있다.
var 변수이기에, 엔진은 호이스팅 동안 undefined 값을 할당할 것이다.

🔥함수 선언식은 호이스팅에 영향을 받지만, 함수 표현식은 호이스팅에 영향을 받지 않는다.

✅ 변수의 선언

변수는 3가지 단계를 거쳐 생성

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

👻 Var

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

👻 let과 const 호이스팅

let과 const로 선언한 변수도 호이스팅 대상이지만, var와 달리 호이스팅 시 undefined로 변수를 초기화하지는 않는다.
따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외(참조 에러)가 발생한다

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

💡 var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다.
➡️ 초기화 단계에서 undefined로 초기화되기 때문에 변수 선언문 이전에 변수에 접근해도 에러가 발생하지 않고 undefined를 반환하는 것
💡 반면 let, const 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 이루어진다.
➡️ 따라서, 스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어지므로 초기화 이전에 변수에 접근하면 참조 에러(ReferenceError)가 발생하는 것

🤔 TDZ

let,const 로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점(변수 선언문)까지 변수를 참조할 수 없다.
let, const 가 동작하는 과정에서 스코프의 진입지점과 해당 식별자의 실질적 선언부 사이를 일시적 사각지대, TDZ(Temporal Dead Zone) 라고 한다.

여기서 변수는 존재하지만, 초기화가 되어있지 않다.


MDN
호이스팅 영문 자료
호이스팅 블로그 - 영문자료해석
Github - prepare_frontend_interview

0개의 댓글