본문 바로가기
FE/JavaScript

[JavaScript] 변수 선언과 호이스팅

by thedev 2022. 10. 12.

 

변수 선언과 변수 호이스팅

 


 

# 변수 선언

 

 변수 선언이란? 변수를 생성하는 것이다. 메모리 공간을 확보하고, 변수의 이름과와 메모리 공간의 주소를 연결하여 값을 저장할 수 있게 준비해주는 것을 의미한다.

 

let name;

 

 name이라는 변수를 선언했다. 그렇다면 메모리는 값을 저장하기 위한 공간을 확보하고, 그 공간을 name이라는 변수가 사용하도록 해줄 것이다. 단, 아직 아무런 값이 할당되지 않았다. 그럼 메모리 공간이 비어있는 것일까? 그렇지 않다. 값을 할당하지 않았다면 메모리 공간은 자바스크립트의 엔진에 의해 undefined라는 값이 할당된다.

 

 즉, 변수 선언의 과정은 다음과 같다.

 

 1. 선언 : 변수의 이름을 선언해서 자바스크립트 엔진에 변수의 존재를 알린다.

 2. 초기화 : 변수에 값을 저장할 수 있도록 메모리 공간을 확보하고 암묵적으로 undefined를 할당한다.

 

 변수를 사용하려면 반드시 변수를 선언해야 한다. 변수를 선언하지 않고 사용하려 하면 참조 에러가 발생한다. 참조 에러란, 자바스크립트 엔진이 식별자*를 찾을 수 없을 때 발생하는 에러이다.

 

*식별자 : 어떤 값을 구별해서 식별할 수 있는 고유한 이름. 변수 이름, 함수 이름 등이 이에 해당한다.

 

 

# 변수 호이스팅

 

console.log(text); // undefined
let text = "hello";

 

 자바스크립트 코드는 인터프리터에 의해 한 줄씩 차례대로 실행된다. 이 때문에, 위 예시에서 text라는 변수는 선언되기 전에 실행된다. 그렇다면 예시 상황에서는 참조 에러가 발생할까? 답은 아니다. 참조 에러는 발생하지 않고 undefined가 출력된다. 그 이유는 변수 선언의 실행 시점을 보면 알 수 있다.

 

 자바스크립트의 소스코드가 한 줄씩 실행되는 그 시점을 런타임이라고 한다. 그리고, 변수 선언은 런타임 이전에 먼저 실행된다. 자바스크립트의 엔진은 소스코드를 실행하기 전에 미리 준비를 한다. 그리고 이 준비 과정에서 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 먼저 실행하고, 이 과정이 끝난 다음에 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행한다.

 

 즉, 변수 선언은 어느 위치에 있든 다른 코드보다 먼저 실행된다. 따라서 변수 선언 이전에 변수를 선언하여도 참조 에러가 아닌 undfined 값이 출력되는 것이다. 이렇게 변수 선언문이 코드의 가장 앞으로 온 것처럼 동작하는 것을 변수 호이스팅이라고 한다. 이는 자바스크립트 고유의 특징이며, 변수 뿐만 아니라 함수, 클래스 등 식별자는 모두 런타임 이전에서 먼저 실행된다.

 

 

# 값의 재할당

 

let age = 20;
age = 21;

 

 let으로 선언한 변수는 값을 재할당할 수 있다. age라는 변수에 초기값을 20으로 할당한 뒤 21로 변경하였다면 메모리 공간은 새로운 메모리 공간을 확보하고 그 공간에 숫자 21을 넣는다. 기존에 존재하던 age = 20을 바꾸는 게 아니라, 새로운 age = 21이라는 메모리 공간을 만드는 것이다. 가장 처음 변수를 선언했을 때 undefined가 할당되고, 20이라는 값을 할당했다가 21이라는 값이 할당되는 과정은 다음과 같다.

 

변수 선언, 값 할당, 재할당 과정

 

 age는 더 이상 undefined와 20이라는 값을 사용하지 않는다. undefined와 20은 아무도 사용하지 않는 값이 된 것이다. 그렇다면 이 값은 어떻게 될까? 가비지 콜렉터라는 기능에 의해 메모리에서 해제된다. 단, 해제가 언제 되는지는 알 수 없다.

 


 

참고 자료 : 모던 자바스크립트 Deep Dive 4장