자바스크립트의 호이스팅

Grace·2022년 8월 10일
5

javascript

목록 보기
2/2
post-thumbnail

썸네일에 이끌려 들어오셨다면 감사합니다 ㅎ

최근에 2시간을 본 면접이 있었다.

나는 단답을 하는 성향은 아니라서, 기술적인 부분이 아니라면(ㅋ) 말이 많은 편이라 그런지
꽤나 오랜 시간을 앉아있었다.
면접관이 통신쪽만 10년을 넘게 개발을 해오신 분이었기 때문에 프론트엔드에 대한 개념이
그다지 확실히 잡혀있지 않은 분이셨는데, (본인이 말씀하기로는..)
그 중, 자바스크립트의 호이스팅에 대해 서로 토론하듯이 얘기하던 시간이 있었다.
개념적인건 알지만, 깊이있게 알지 못하다보니 이래서 이런거 아닐까요? 라는 식의 대화였는데,
생각보다 흥미로운 시간이었어서, 제대로 정리해두고자 포스팅을 작성해보려고 한다.


javascript hoisting

인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것으로,
변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는 것으로 이해할 수 있다.

호이스팅의 대상

var는 물론이고, ES6부터 도입된 let, const을 포함한 모든 선언을 호이스팅하게 된다.
변수는 3가지 단계를 거치면서 생성되는데,

  1. 선언 단계
    변수를 변수 객체에 등록하게 되는데, 이 변수 객체는 scope가 참조하는 대상이 된다.
  2. 초기화 단계
    변수객체에 등록된 변수를 위한 공간을 메모리에 확보하는 단계. 이 때 변수는 undefined로 초기화 된다.
  3. 할당 단계
    undefined로 초기화된 변수에 실제 값을 할당하는 단계.

varlet/constscope의 차이로 나뉘어 설명하곤 하는데,
추가적으로 특징이 몇가지가 나뉜다.
📍 var로 선언된 변수는 변수 선언단계와 초기화 단계가 한번에 진행된다.
➔ 선언단계에서 undefined로 초기화를 시켜버리기 때문에, 변수 선언문 이전에 변수에 접근해도 에러가 아닌 undefined를 출력하게 되는 것.
📍 반면, let/const로 선언된 변수는 변수 선언단계와 초기화단계가 분리되어 이루어진다.
➔ 때문에 scope에 변수를 등록(선언) 하지만, 초기화단계는 변수 선언문에 도달했을 때 이루어지므로, 초기화 이전에 변수에 접근하려 하면 참조에러(ReferenceError)가 발생하게 된다.

블로그를 돌아다니다보면, let과 const는 호이스팅이 되지 않는다 라고
말하는 사람들이 있는데,
(실제로 면접에서도 그러신 분이 계셨기 때문에,,)

let과 const가 호이스팅이 되지 않는 것 처럼 보여지는 것일 뿐,
변수가 초기화되기 전에 ReferenceError를 발생시키는 것이지 호이스팅이 되지 않는건 아니다.
실제로 let을 선언 전에 사용하여 발생하는 에러를 살펴보면,

ReferenceError로, 초기화 이전에 엑세스 할 수 없다는 내용의 에러다.

이는 아래에서 말할 일시적 사각지대(TDZ)와 관련이 있다.

⚠️ 일시적 사각지대(Temporal Dead Zone, TDZ)

TDZ는 scope의 시작지점부터 초기화 단계 시작 지점까지의 구간을 의미한다.

// var 사용 시
(function test() {
  console.log(a);
  var a;
}()); // undefined => var로 선언한 a는, 선언과 동시에 undefined로 초기화 설정이 된다.

// let 사용 시
(function test() {
  console.log(b); // TDZ구간
  let b;
}()); // ReferenceError => let으로 선언한 b는, 선언만 됬을 뿐 초기화 설정이 되지 않기 때문에 참조에러가 난다.

때문에 위 코드에서의 TDZ는,
let을 사용한 경우에 선언 이전에 변수를 사용한 구간(console.log)을 말한다.


추후에, 언젠가 내가 면접관이 되는 기회가 있다면,
질문을 통해 면접자의 답만 받아내는 것이 아니라
이번에 내가 경험했던 것 처럼, 서로의 의견을 주고받을 수 있는 주제면 좋겠다는 생각을 했다.

참고하였습니다 :)

profile
쉽게 사는건 재미가 없더군요, 새로 시작합니다🤓

2개의 댓글

comment-user-thumbnail
2022년 9월 5일

좋은 글 감사합니다! 면접 결과는 괜찮으셨는지 ㅠ

1개의 답글