본문 바로가기
Web Frontend/JavaScript

[ JavaScript ] 호이스팅: 변수와 함수의 동작 방식 및 결과의 차이점 비교

by quessr 2023. 5. 22.

호이스팅이란?
변수나 함수가 어디서 선언되든지 해당 스코프 최상단에 위치하게 되어 동일 스코프 어디서든 참조할 수 있는 것을 말한다.

호이스팅은 변수와 함수의 동작 방식에 따라 출력 결과가 다르게 나타나는데, 이러한 차이점에 흥미를 느껴 각각의 경우를 자세히 정리하고자 한다.

먼저, 호이스팅에 따른 출력값이 각각 다르게 나타나는 것을 이해하기 위해서는 선언 참조, 초기화 개념을 알아야 한다.

선언이란,
변수나 함수를 정의하고 해당 이름을 사용할 수 있도록 식별자(변수 이름)을 지정하는 것이다.
변수선언은 var, let, const를 사용할 수 있고,
함수선언은 function을 사용할 수 있다.

참조란,
선언된 변수나 함수에 접근하여 값을 읽거나 변경하거나 함수를 호출하는 것을 의미한다.
변수나 함수를 참조할 때는 해당 식별자를 사용하여 참조한다.

초기화란,
쉽게 말해서 변수와 함수와 함수를 사용 가능한 상태로 만드는 과정을 의미한다.
변수 초기화: 변수를 선언한 후에 값을 할당하는 과정, 변수를 초기화 함으로써 변수는 할당된 값을 가지고 해당 값에 접근할 수 있게 된다.
함수 초기화: 함수를 선언한 후에 해당 함수를 호출할 수 있는 상태로 준비하는 과정, 함수를 초기화 함으로써해당 함수를 호출하여 원하는 작업을 수행 할 수 있다.


이제 위의 도식을 보면서 하나하나 설명을 해 보자면,


1. 변수 선언의 경우

var로 선언한 변수는 호이스팅에 의해 변수선언과 초기화가 동시에 이루어진다. 선언 단계에서 변수가 메모리에 할당되고, 초기화단계에서 undefined로 초기화가 된다. 따라서 변수 선언 전에 변수를 참조해도 에러가 발생하지 않고 undefined가 출력된다. 
let과 const는 선언과 초기화가 따로따로 일어나는 변수로 호이스팅에 의해 선언 단계만 호이스팅되고 초기화는 호이스팅되지 않는다.
즉, 변수선언은 스코프 상단으로  이동하지만 초기화는 실제 코드의 위치에 남아 있는다.
따라서 변수를 선언하기 전에 변수를 사용하려고 하면 ReferenceError가 발생하게 된다.

위와 같이 간단한 로직을 작성하여 확인해 보면,
var로 선언된 변수 x의 경우 선언되기 전에 출력하면 에러가 발생하지 않고 undefined가 출력되며
이후 값이 할당되면 할당된 값이 출력이 되는것을 확인 해 볼 수 있다.

let으로 선언된 변수 y의 경우에는 선언되기 전에 출력하면
변수 y가 아직 초기화 되지 않아 접근할수 없다는 ReferenceError가 출력되는 것을 확인 해 볼 수 있다.

2. 함수 선언의 경우


함수 선언 에는 두 가지 방식이 있다. 함수 선언식과 함수 표현식이다.
함수 선언식:function을 사용하여 함수를 정의하는 방법.
함수 표현식: 함수를 변수에 할당하는 방법.

함수 선언식의 호이스팅
함수 표현식의 호이스팅


함수 선언식과 함수 표현식은 호이스팅의 동작 방식에서의 차이가 있다.

위의 코드에서와 같이 함수 선언식의 경우는 선언과 동시에 초기화가 되기 때문에 함수 정의 이전에 호출을 해도 동작 하지만,

함수 표현식은 변수에 함수가 할당되는 방식으로,
호이스팅에 의해 변수 add는 선언되지만 초기화되지 않기 때문에 함수를 참조하기 전에 호출하면 TypeErrorr가 발생한다.
즉, 변수의 호이스팅 동작에 영향을 받아 변수 선언 이전에 함수를 호출하면 에러가 발생한다.