자바스크립트 변수의 생성과정과 호이스팅 개념

JS의 변수 생성 과정

자바스크립트 엔진은 변수 선언을 다음과 같은 단계에 거쳐 수행한다.


1. 선언 (실행 컨텍스트에 등록하여 자바스크립트 엔진에 변수의 존재를 알린다) => 스코프가 참조
2. 초기화 (메모리에 공간 확보, undefined를 할당하여 초기화)
3. 할당 (실제 값 할당)

 

 

실행 컨텍스트

실행 컨텍스트는 코드가 실행되기 위해 필요한 환경.

 

- 모든 JavaScript 코드는 실행 컨텍스트에서 실행되며, 실행 컨텍스트는 코드 실행에 필요한 환경 정보를 제공한다.
- 자바스크립트 엔진은 실행 컨텍스트를 관리하며 선언된 코드가 등록됨.
실행 컨텍스트는 코드가 실행되기 전 메모리에 변수를 할당하고 실행할 준비를 마친다.

 


JS 엔진은 코드를 실행하기 전 코드를 형상화하고 구분하는 과정을 거친다.

즉, 자바스크립트 엔진은 (실행 컨텍스트를 위한 과정) 에서 모든 선언을 스코프에 등록한다.

자바스크립트 엔진은 변수 선언이 소스코드의 어디에 있든 상관없이 다른 코드보다 먼저 실행한다.

 

따라서 변수 선언이 어디에 위치하는지와 상관없이 어디서든지 변수를 참조할 수 있다. 이처럼 변수 선언문이 코드의 선두로 끌어올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅 이라고 한다.

 

이 변수가 var 인 경우 undefined로 초기화된다.

하지만 모든 변수의 실제 값의 할당은 결국 할당문에서 이루어진다는 것을 명심해야한다.

 

 

호이스팅

변수의 생성과 실제 값의 할당이 각각 다른 시점에 실행되는 문제로 인해
변수를 선언한 위치에 상관없이 최상단에 선언된 것처럼 동작 하는 것.

 

선언이 먼저 메모리에 저장되는 것.

선언이 끌어올려지는 것.

 

자바스크립트의 모든 선언에는 호이스팅이 일어난다.. !!

그런데 let, const, class를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다. 

 

 

왜 호이스팅이 발생할까?

var 의 경우 위의 1,2가 동시에 일어난다.

따라서 var 키워드로 선언한 변수는 어떠한 값이 할당되지 않아도 undefined라는 값을 갖는다. 

 

console.log(score); //undefined
var score; //변수 선언문

 

자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행되므로 console.log 가 가장 먼저 실행되고, 순차적으로 다음 줄에 있는 코드를 실행한다. 따라서 console.log 가 실행되는 시점에는 변수의 선언이 실행되지 않았으므로 참조에러(Reference Error)가 발생할 것처럼 보인다. 하지만 var의 경우, 참조 에러가 발생하지 않고 undefined가 출력된다.

 

 

그 이유는 소스코드가 한 줄 씩 순차적으로 실행되는 시점(즉 런타임),  보다 먼저 변수 선언이 실행되기 때문이다.

 


 

변수 선언과 값의 할당을 두 개의 문으로 나누어 표현한 코드와 변수 선언과 값의 할당을 하나로 단축 표현한 코드는 정확히 동일하게 동작된다. 자바스크립트 엔진은 변수 선언과 값의 할당을 하나의 문으로 단축 표현해도 변수 선언과 값의 할당을 두 개의 문으로 나누어 각각 실행한다.

 

var score; //변수 선언
score = 80; //값의 할당
var score = 80; //변수 선언과 값의 할당

 

위의 두 코드는 정확히 동일하게 표현된다. 

 

 

 

즉, 변수의 선언과정을 정리해보면...

  1. var 는 선언과 함께 undefined로 초기화되어 메모리에 저장되는데,
  2. let 과 const 는 초기화되지 않은 상태로 선언만 메모리에 저장된다.
  3. 초기화되지 않으면 변수를 참조할 수 없어 참조 에러를 일으킨다. (let, const) 

 

 

여기서 중요한 점은 변수 선언과 값의 할당이 실행 시점이 다르다는 것이다.

변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만, 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다. 

 


ref :