본문 바로가기
FE/Javascript

hoisting

by ideal_string 2022. 9. 11.

호이스팅은 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다. 보통 변수를 선언하고, 할당한다. 또는 선언과 동시에 할당하거나 재할당하기도 한다. 이때 어떤 자료형을 쓰느냐에 따라 호이스팅이 일어나기도, 없기도 한다. var 선언, let 선언, const 선언, 그리고 함수 선언식, 함수 표현식를 통해 호이스팅을 알아보고자 한다.

자바스크립트 ES6에서는 var보다 let과 const 사용을 권장한다. let과 const는 ECMAScript® 2015(ES6)에서 처음 나온 것으로 이전엔 var만 존재했고, var가 자바스크립트의 일반적인 사용방식이었다. ES6에서 var를 두고 let과 const 선언을 따로 만든 이유 중 하나가 바로 호이스팅이다. 호이스팅이 무엇인지 우선 코드를 보자.

 

console.log(a);

var a="저는 var입니다.";

console.log(a);

위와 같이 a를 출력하는 코드를 작성했다. 첫번째는 undefined, 두번째는 "저는 var입니다."를 출력한다. let 과 const를 위와 같이 작성해보자.

 

console.log(b);
console.log(c);

let b="저는 let입니다.";
const c="저는 const입니다.";

console.log(b);
console.log(c);

위 코드를 실행하면 첫줄에서 오류가 난다. "Uncaught ReferenceError: b is not defined" b 자체가 정의 되지 않았다는 오류. 즉 선언도 되지 않았다는 말이다. var과 전혀 다른 결과값을 보여준다.

 

이 결과의 차이가 호이스팅을 뜻한다. var은 선언과 동시에 코드 최상단으로 끌어올려져 선언이 먼저 되고, 후에 코드가 있는 해당 줄에 왔을 때 값이 할당된다. 선언이 최상단으로 끌어올려지는 것 현상을 호이스팅이라 부른다. var와 달리 let과 const는 코드가 있는 곳까지 와야 선언과 할당이 메모리에 저장된다. 따라서 선언 전엔 해당 값을 사용할 수도 인식할 수도 없다. 자바스크립트는 인터프리터 언어이기 때문에 위에서부터 한줄씩 실행됨에도 불구하고 코딩을 의도한 바대로 움직이지 않았음을 알 수 있다.

 

// var선언을 사용하면 항상 다음과 같이 프로그래밍된다고 생각하자.
var a;

console.log(a);

a="저는 var입니다.";

console.log(a);

호이스팅의 동작 순서

1. 자바스크립트 Parser가 함수 실행 전 해당 함수를 한번 훝는다.

2. 함수 안에 있는 변수 혹은 함수 선언에 대한 정보를 기억하고 있다가, 코드 작동 시 먼저 실행한다.

다만, 함수 블록(해당 스코프) 안에서만 유효하고 실제 코드가 끌어올려지는 게 아니라 parser 내부적으로 끌어오려 처리할 뿐이다. 그러므로 메모리에서의 변화도 없음을 기억하자.

왜 호이스팅이 문제인가

1. 우리는 보통 선언과 할당을 동시에 진행한다. 이 상태를 초기화라 부르는데, var를 사용한다면 우리가 원치 않았던 초기값(undefined 등)이 들어간다. 

console.log(a);

var a="저는 var입니다.";

console.log(a);

 

2. var는 중복 선언이 가능해 호이스팅이 될 경우 원치 않은 결과값을 볼 수 있다.

onsole.log(a); //undefined

var a="저는 var입니다.";

console.log(a); //저는 var입니다.

var a=123
var a="아무도 이변수는 사용하지 않았겠지...!"

console.log(a); //아무도 이변수는 사용하지 않았겠지.. !

let과 const도 호이스팅이 된다?!

맞다. let과 const도 사실, 호이스팅 된다. 다만, TDZ에 있을 뿐이다. TDZ는 Temporal Dead Zone의 약자로 임시로 죽은 공간을 뜻한다. let과 const도 호이스팅되어 상단으로 끌어올려지지만, 바로 선언되지 않고 TDZ란 곳에 두었다. var처럼 선언되지 않게 하는 방법을 새로 고안한 것. 따라서, 호이스팅이 되지만 실행되지 않는다고 이해하면 될 듯하다.

 

함수 호이스팅

변수와 상수를 선언하는 var, let, const 뿐만 아니라, 함수도 호이스팅 된다. 함수 선언식은 var, 함수 표현식(화살표 함수)는 let(const)와 동작 방법이 같다.

 

주의점

호이스팅으로 작동하는 var 선언과 함수 선언식에서 같은 이름을 사용할 경우 변수 선언이 더 상단에 올려진다.

  var myName = "hi";

  function myName() {
      console.log("idealstring");
  }
  function yourName() {
      console.log("hi");
  }

  var yourName = "guest";

  console.log(typeof myName); //string
  console.log(typeof yourName); //string

결론

호이스팅으로 원치않은 결과 값이 나타났을 때 코드가 짧다면 금방 발견할 수 있는 오류다. 다만, 코드가 짧지 않다면 어디서 오류가 났는지 파악하기 굉장히 어려워지는 결과가 나타날 듯하다. 따라서 호이스팅이 나타날 수 있는 여지를 주지 않도록 var와 함수선언식 사용을 지양하하고, let과 const, 그리고 함수 표현식(화살표 함수)를 적극적으로 사용해야 한다.

 

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > Javascript' 카테고리의 다른 글

let, const, var  (1) 2022.09.14
Destructuring Assignment  (0) 2022.09.13
loop method - filter, map, every, some  (0) 2022.09.08
import & export  (0) 2022.09.06
try & catch  (0) 2022.09.06