통조림

JavaScript-변수 호이스팅(variable hoisting) 본문

Software/JavaScript

JavaScript-변수 호이스팅(variable hoisting)

고랭지참치 2022. 1. 14. 08:28

 

Javasciprt는 ES6버전 이전까지 var변수만을 지원했다. var 변수는 선언 직후 초기화 단계에서  javascript의 Primitive type인 undefined값을 암묵적으로 할당받게 된다. 이 방식은 메모리의 쓰레기 값을 변수가 참조하지 않도록 방지하는 역할을 했다.

console.log(myValue); //undefined
var myValue;

위의 식을 보면 var 변수 선언 이전 코드에서 console.log 함수를 통해 변수값을 콘솔에 띄우려 한다. 선언 이전에 변수를 사용하려 하기 때문에 참조 오류가 출력될 것이라고 예상할 수 있지만, 콘솔에는 undefined라는 값이 정상적으로 출력된다.

이 이유는 JavaScript에서 변수 선언은 코드가 실행되는 런타임 시점이 아니라 그에 앞선 시점에서 실행되기 때문이다.

JavaScript 엔진은 전체코드 중 위치와 상관없이 번수 선언 부분을 다른 코드들보다 우선하여 실행한다. 덕분에 코드 위치와 상관없이 어느 곳에서든 변수를 참조할 수 있게 된다. 이렇게 변수 선언이 우선되는 것을 변수 호이스팅이라고 한다.


console.log(myValue);
//Uncaught ReferenceError: Cannot access 'myValue' before initialization

let myValue;

JavaScript에서 변수 호이스팅은 var 타입뿐만 아니라 다른 모든 식별자에 적용된다. 그러나 위의 코드의 변수 타입을 var가 아닌 let으로 바꾸면 위 코드의 주석과 같은 참조 에러 메시지가 출력된다.

아니 호이스팅이 똑같이 적용된다고 하면서 왜 안 되는 거지?라는 물음으로 이유를 찾았다. 그 이유는 var 타입과 let, const 등의 타입의 변수 선언 할당 방식이 다르기 때문이다. 

var 변수타입에 대한 맨 위 설명처럼 var타입의 변수는 선언과 동시에 undefined값으로 초기화가 진행된다. 때문에 var변수를 할당 이전에도 참조할 수 있게 된다. 

 

그러나 let 타입으로 선언된 변수는 선언 시점과 초기화 단계가 구분되어 있기 때문에 초기화가 되기 전에 변수값을 참조하려고 한다면 참조에러가 발생한다. 선언과 초기화 단계 사이의 변수값을 참조할 수 없는 구간을 Temporal Dead Zone(TDZ)라고 부른다.

let과 const 변수등의 TDZ로 인해 Hoisting이 적용되는 것인지 확인할 수 없어 보이지만, function-level-scope 외에는 모두 전역변수로 선언되는 var와 다르게 let과 const 는 Block-scope가 적용된다.

let myValue = 1;

{
	console.log(myValue); //ReferenceError
	let myValue = 1;
}

 

위 코드의 let 변수는 black-scope 안에서 호이스팅이 이루어졌기 때문에 참조에러를 출력한다.

참고 : 이웅모. 『모던 자바스크립트 Deep Dive』. 위키북스 2020.