프론트엔드 단골 면접질문. 호이스팅

최근에 회사를 그만두는 동료와 차 한잔을 같이 했는데요. 그 분이 면접을 보았는데 프론트엔드 면접 단골 질문인 호이스팅이 나왔답니다. 그분은 함수나 변수가 위로 끌어올려지는 자바스크립트 기능 이라고 대답했다는데요. 그때부터 실행컨텍스트와의 상관관계 등 면접관의 꼬리물기 질문이 나왔다고 합니다. 왜 면접관은 그때부터 꼬리물기 질문을 했을까요? 제 생각에는 답변이 잘못되었기 때문입니다. 호이스팅을 네이버 영어사전에서 검색해보면 'The behaviour of Javascript syntax which allows variables to be used before they are declared' 라고 나옵니다. 즉, 자바스크립트 문법에서 변수나 함수를 선언 이전에 사용할 수 있다는 뜻입니다. 즉, 호이스팅은 정말로 위로 끌어올려지는것이 아니고, 변수나 함수를 선언 이전에 사용할 수 있기 때문에 끌어 올려지는 것처럼 보이는 것일 뿐입니다. 그럼 어떻게 선언 이전에 사용할 수 있을까요?? 실행컨텍스트가 생성될때, 변수 객체 에 배열 식별자 정보를 담는 variable 배열에 변수들을 먼저 담습니다. 먼저 담기 때문에 선언을 나중에 해도 사용이 가능한것이죠. 그럼 var 와는 달리 const 나 let 은 어떻게 호이스팅 되지 않고 TDZ 에 들어가는것일까요? var 는 선언과 동시에 AllocateTo 메소드를 통해 메모리에 바로 할당이 됩니다. 하지만 const 나 let 은, set_initializer_position 메소드를 통해 해당 코드의 position를 정해주어 초기화 해주는 과정을 거칩니다. 즉, var 와는 달리 메모리 할당 이전에 일종의 방어코드가 추가됨으로써, 선언은 되어 있지만 변수에 값을 담기 위한 메모리에 공간이 확보되지 않은 상태가 되는 것이죠. 즉, const 나 let 또한 동일하게 실행컨텍스트가 생성되는 시점에 variable 배열에 담겨 호이스팅이 되지만 일종의 초기화(set_initializer_position)로 인해 선언이나 할당 이전에 미리 사용할수 없게 된것이죠. 면접을 준비할때, 자주 나오는 질문들은 깊게 파악하는 것이 좋습니다. 면접을 준비하는 과정이 힘든 부분도 있지만 평상시 실무만 해서는 알기 힘든 내용을 깊이 파악할 수 있는 더 나은 개발자가 되기 위한 기회가 되기도 하는것 같습니다.

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2022년 10월 1일 오전 12:21

 • 

저장 421조회 16,218

댓글 11

  • 감사합니다 실행컨텍스트를 이해하려고 하면 호이스팅이랑 스코프, 클로저는 자동까지는 아니더라도 이해하기가 훨씬 수월하더라구요.

  • 좋은 글 감사합니다 ㅎㅎ

  • 글을 읽어도 잘 이해가 가지않습니다. 어려운 개념인가요 😃

  • 삭제된 사용자

    2023년 10월 24일

    C언어의 Extern을 공부하시면 더 쉽게 이해하실 수 있습니다!

  • 개인적으로 저는 호이스팅이 변수를 끌어 올리는 것처럼 사용하는 것이라고 말해도 된다고 생각합니다. 당연히 기능적으로는 글쓴이 분 설명처럼 실제로 끌어 올리는 것이 아니라, 실행 컨텍스트가 각 변수와 함수의 식별자가 담긴 "환경 레코드"를 보고 어어? 이런 변수와 함수가 있어? ㅇㅋ 알겠음. 이렇게 미리 인지하고 소스를 돌면서 실행, 실행, 실행 하는 것이죠. 하지만 우리가 인지하는 실행 컨텍스트는 소스를 기준으로 항상 "위에서 아래"로 읽어나간다는 것이고 내가 실행하려는 변수와 함수를 지나지도 않았는데 이를 미리 알고 있으니 위로 끌어올려진 것처럼 보이죠. 그런데, 이런 식이면 사실 우리가 javascript에서 쓰고 있는 배열도 실은 배열로 부르면 안됩니다. 배열이라함은 데이터를 실제 메모리에 연속적으로 담고 있어야 하는데 javascript는 사실 그렇게 동작하고 있지 않죠. 배열의 항목들을 주소값으로 연결하여 마치 실제 배열처럼 이어진 데이터로 착각하게 만들어 주는 것이죠. 사실 저도 개발한지 좀 되었고 아직도 뭣도 모른채로 개발하고 다니지만, 갠적으로는 저렇게 직관적인 설명이 좋습니다. 물론 그 직관을 풀어 설명할 수 있는 백그라운드가 있으면 더 좋겠지만요.

    @제일 좋은 의견 감사합니다. 먼저 오해가 있으신것 같은데요. 호이스팅이 변수를 끌어 올리는 것처럼 사용하는 것이라고 당연히 이야기 해도 됩니다. MDN에서도 '함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상' 이라고 정의하고 있습니다. 다만 제 지인이 답변한 '함수나 변수가 위로 끌어올려지는 자바스크립트 기능' 이라는 답변이 잘못되었다고 말씀드린겁니다. 실제로 위로 끌어올려지는건 아니니까요. 배열의 예시같은 경우는 MDN 에서 '여러 항목의 컬렉션을 단일 변수 이름 아래 저장할 수 있다' 고 정의하고 있습니다. 즉 JavaScript의 배열은 내부적으로 메모리에 연속적으로 담기는 '배열'과의 전통적인 정의와는 다소 거리가 있습니다. 하지만 프로그래밍 언어의 문맥에서 볼 때 '배열'이라는 용어는 단순히 메모리에 연속적으로 배치된 데이터 구조를 의미하는 것이 아니라, 여러 데이터 항목을 하나의 변수 이름 아래에 순차적으로 저장하는 어떤 형태의 구조를 가리키는 데 사용됩니다. 즉, 자바스크립트의 배열도 배열이라고 부를수 있습니다.

    @김의중 태클처럼 들리실 수도 있겠지만 어느 부분이 오해인지 모르겠습니다. (제가 생각하는) - 사전적 의미의 호이스팅 = 변수나 함수를 최상단으로 끌어올리는 것 (글쓴이 분이 말씀하신) - 기능상 실제로 호이스팅 = 호이스팅은 정말로 위로 끌어올려지는것이 아니고, 변수나 함수를 선언 이전에 사용할 수 있기 때문에 끌어 올려지는 것처럼 보이는 것 (글쓴이 분께서 생각하는) - 사전적 의미의 배열 = 단순 메모리가 아닌 순차적으로 저장하는 자료구조 형태 (제가 생각하는) - 기능상 실제 배열 = 자료구조상의 배열은 무조건 메모리 공간을 위해서 앞뒤로 붙여서 저장되는게 맞음. 호이스팅도 구현체단계까지 보면 변수를 끌어 올리는게 아니듯 배열도 구현체까지 보면 데이터를 일렬로 저장 안함. 심지어 javascript 배열은 요소마다 할당하는 메모리 크기마저 다름. 결국 javascript는 거기서 얻는 성능절감효과가 미미해서 이부분을 포기하고 배열이 아닌 것을 배열처럼 보이게 해서 만든 기능임. 호이스팅은 구현체까지 보셔서 실제 함수와 변수가 위로 끌어 올려지는 기능이 아니라고 말씀하셨는데 배열은 왜 구현체까지 보지 않으시고 의미적인 부분으로만 보시는지에 대해서 이해가 가지 않았습니다. 배열도 의미상 연속적으로 배치된 데이터를 의미하는 것일 뿐이라면 호이스팅도 의미상 배치된 변수와 함수를 최상단으로 끌어올리는 것이 전혀 어폐가 없어보인다는 생각이 들어서요. 결국 자바스크립트의 배열도 배열이 맞다는 말씀하신다는건 자바스크립트의 호이스팅도 영문 그대로 "끌어올리다"가 맞는것일진데, 제가 어느 부분을 오해하고 있는지 이번 기회에 잘못된 부분을 고치고 싶어 다시 질문드립니다.