호이스팅은 var 에서만 일어난다구요?

오재짱·2021년 8월 18일
1

JavaScript

목록 보기
2/4
post-thumbnail

참조 에러가 아닌 undefined?

개념을 공부할때 가장 쉽게 이해할수 있는 방법 중 한 가지는 코드를 통해 확인해보는것입니다. 먼저 아래의 코드를 통해 살펴보도록 하겠습니다.

console.log(name); // undefined

var name;

선언되지 않은 변수를 참조할 수 있을까요? 선언되지 않은 변수를 참조하려 한다면 이를 알려주는 가장 대표적인 에러로 참조 에러인 ReferenceError가 발생해야 합니다. 하지만 자바스크립트에서는 참조 에러 대신 undefined가 출력되는 것을 확인할 수 있습니다.

그 이유는 바로...

이런 현상이 발생하는 이유는 자바스크립트에서의 변수 선언문은 런타임이 아닌 런타임 이전 단계에서 먼저 실행되기 때문입니다.

자바스크립트의 엔진은 소스코드를 실행하기 전에 먼저 준비 단계를 거칩니다. 이러한 과정을 소스코드의 평가 과정이라고 부릅니다. 

소스코드의 평가 과정

소스코드의 평가 과정을 통해서 자바스크립트 엔진은 모든 선언문들을 먼저 샅샅이 찾아냅니다. 이후 다른 코드들보다 먼저 실행시킵니다.


샅샅..샅샅...

이 과정이 마무리되면 비로소 소스코드를 실행할 준비가 됬음을 알립니다.


준비완료!

런타임에서 일어나는 변수 호이스팅

이제 소스코드를 실행하는 런타임에 들어가게 됩니다. 이미 소스코드의 평가 과정에서 선언문들을 먼저 실행했기 때문에 런타임에서는 선언문을 제외한 소스코드만 한 줄씩 실행합니다.

이미 변수 선언문이 실행되었기 때문에 런타임에서는 모든 변수들이 선언되어 있는 상태입니다. 이 때문에 런타임이셍 변수 선언문이 맨 밑에 있더라도 마치 맨 위에 있는것처럼 동작합니다.

즉 아무리 아래에 있더라도 마치 제일 위로 끌어올려진것처럼 동작합니다. 이를 변수 호이스팅이라고 부릅니다.

이렇게 끌어올립니다.

대부분이 잘못 알고 있는 사실

그렇다면 아래와 같은 코드에서는 어떨까요? 

console.log(name); // 참조에러가 발생합니다.

let name;

이번에는 정확하게 참조 에러가 발생했습니다. 그렇다면 let 의 경우는 변수 호이스팅이 일어나지 않는 것처럼 보입니다. 하지만 이는 잘못 알고 있는 사실입니다.


정말?

var 에서만 호이스팅이 동작하는게 아닌가요?

만약 var 키워드로 변수를 선언하면 자바스크립트 엔진은 암묵적으로 선언과 초기화를 동시에 진행합니다. var 키워드로 선언한 변수는 선언됨과 동시에 undefined라는 값이 할당되게 됩니다. 이후에 변수 할당문을 만나면 그때 변수 값이 할당되는 방식으로 진행됩니다.

let 키워드의 경우는?

let 키워드는 var 키워드와 다르게 동작합니다. let 키워드는 변수 선언 단계와 초기화 단계가 분리되서 진행됩니다. 암묵적으로 선언 단계가 먼저 실행되지만 값의 초기화는 변수 선언문을 만났을 경우에 실행됩니다. 

참조 에러는 초기화가 되지 않은 변수에 접근하는 경우에 발생하게 됩니다. 즉 var 키워드와는 다르게 let 키워드가 초기화되기 전에는 참조가 불가능하기 때문에 참조 에러가 발생하는 것입니다.

모든 선언들은 호이스팅이 발생한다.

let name = 'wonjae';

{
  console.log(name); // ReferenceError: Cannot access 'name' before initialization
  let name = 'wonjaeoh';
}

위 코드의 경우 만약 호이스팅이 일어나지 않는다면 name 은 wonjae 가 출력되어야 합니다. 하지만 전역의 name 이 있음에도 불구하고 참조 에러가 발생합니다.

여기서 지역에 존재하는 name이 호이스팅이 발생했기 때문에 전역에 있는 name이 아닌 지역에 있는 name을 참조하고 있습니다. 

즉, var 키워드에서만 호이스팅이 일어나는것이 아니라 모든 선언문들은 사실 호이스팅이 발생합니다. 하지만 마치 일어나지 않는것처럼 눈속임을 하는 것 뿐입니다.


대박이죠?

결론

호이스팅에 대해서는 잘 알고 있는 분들이 많습니다. 면접 준비를 하면서 여러 글들을 찾아보던 와중 대부분의 사람들이 호이스팅에 대해 let, const 의 경우에 일어나지 않는다는 글이 있어 정리해보게 됬습니다.

코드를 통해서 확인하는것이 가장 빠릅니다. 아무리 많은 사람들이 맞거나 틀리다라고 얘기한들 스스로가 확인해보고 납득하지 않으면 소용없다고 생각합니다★ 읽어주시는 모든 분들 감사합니다♥

profile
'설명하지 못하면 이해한게 아니다'라는 마음가짐을 가진 프론트엔드 지망생에서 프론트엔드 개발자가 됬습니당!

0개의 댓글