본문 바로가기
프로그래밍/JavaScript

[JS] # 1. 호이스팅 (Hoisting) & TDZ (실행컨텍스트와 var,let,const)

by Crush on Study 2024. 7. 18.
반응형

호이스팅은 JS를 다뤄본 적이 없으면 처음 듣는 개념일 수도 있다.

이름 그대로 해석하자면 "끌어올리다" 라는 뜻인데, JS만의 특별한 기능이다.

 

print(a)
a = 5;

 

이 코드를 vscode에서 돌려보면  a가 정의되지 않았다며 NameError가 뜬다.

당연하다. 코드라인을 탑다운 식으로 읽어가고 있으니까!

 

console.log(a);
var a = 5;

 

근데 얘는 심상치가않다. vscode에서 파이썬 코드를 작성하면 벌써부터 에러 표시 밑줄이 뜨는데, 얘는 아니다.

설마? 하고 돌려보면 "undefined" 라는 문구가 출력될뿐, 에러라고 표현되지는 않는다.

 

왜 그럴까? 이게 바로 호이스팅이다.

호이스팅은 일단 변수가 어디서 선언, 초기화, 할당되었든 최상단으로 "끌어올려진 것" 처럼 동작된다.

 

그럼 여기서 궁금점.

이게 어떻게 가능하지?

 

이 개념은 JS의 "실행컨텍스트" 라는 개념 때문이다. 실행컨텍스트는 코드가 실제로 수행되기 전의 실행환경을 세팅해주는 객체를 말한다. 그 환경을 세팅하는 과정에는 JS로 작성한 코드들 안에 변수선언,함수선언,this 등등의 정보들을 등록시키는 일이다. 

 

이후에 코드를 실행하므로, 코드라인 위치가 이상해보여도 실행컨텍스트 객체에 관련 정보가 들어있기 때문이다.

그래서 변수 a가 있는 것은 알지만 그 값까지는 알지 못하는 것처럼 보인다.

 

OK. 그러면 JS에서는 모든 변수, 그리고 함수도 호이스팅이 되나?

 

호이스팅은 된다. 근데 되지 않는 것처럼 보일 것이다.

일단 변수부터 봐보자. JS가 ES6로 들어서면서 var말고도 let, const 개념이 함께 추가되었다. 무분별한 호이스팅때문에 디버깅에 어려움이 있기 때문이다.

 

console.log(a);
let a = 5;

 

 

이렇게 레퍼런스에러가 뜬다. 이게 무엇인가... 여기서 var와 let, const의 차이가 등장한다.

일단 JS에서 변수는 3단계를 거친다.

 

1) 선언 , 2) 초기화 , 3) 할당

이 3단계를 거치는데 var의 경우는 선언과 동시에 초기화가 이루어진다.

근데 let은 초기화랑 선언이 분류되어있다.

레퍼런스에러 사유를 보면 초기화 전에는 a에 접근할 수 없다는 말이 뜬다.

 

이게 TDZ다

 

어쩌다보니 위 데이터 타입 차이를 말하면서 TDZ의 개념을 같이 말하게 되었다. TDZ 정의는 그냥 저거다. let, const같은 데이터 타입의 경우는 초기화 전에는 변수를 사용하는 것을 허용하지 않는다라고 알고 있으면 된다.

 

그럼 마지막으로 혹시 변수말고도 함수도 호이스팅이 되는지?

함수 표현식과 함수 선언식에 따라 다른데, 결론부터 말하면 선언식은 호이스팅이 된다.

그러나 표현식은 호이스팅이 안되고 TypeError가 뜬다.

 

위에서 실행컨텍스트 얘기를 했는데, 변수 선언과 함수 선언, this가 코드를 실행하기 전에 미리 컨텍스트 객체에 정보가 등록되기 때문이다. 아래 간단한 코드 첨부로 끝!

// 함수 선언식
a(); // hi

function a () {
   console.log("hi");
};

 

// 함수 표현식
a(); // 타입에러가 뜬다.

var a = function() {
    console.log("hi");
};
반응형