호이스팅과 클로저

오다현·2026년 3월 15일
post-thumbnail

호이스팅이란 무엇일까? 호이스팅은 보통 끌어올려진다 라고 표현한다. 하지만 실제로 코드가 위로 올라가는 것은 아니다. 코드 실행 전에 변수나 함수를 미리 메모리에 등록해놓고 실행 단계에서 참조하는 것이라 할 수 있다.

미리 정의하기 때문에 함수가 어디에 정의되어 있는지 정확히 기억하지 않고 어디서든 사용이 가능하다.

자바스크립트 호이스팅 동작 원리로는

문법적 검사 → 메모리에 변수, 함수 등록 → 실행 단계에서 찾아감

이런 흐름으로 동작한다.

var

선언이 먼저 이루어지고 값 할당은 나중에 이루어진다.

console.log(a); // undefined
var a = 10;

var로 선언한 변수는 호이스팅이 일어나면서 할당문 만나기 전까지 선언과 함께 undefined로 초기화된다.


자바스크립트는 이제 웹 애플리케이션을 만들 정도로 복잡해졌고 기능도 많아졌다. var처럼 재선언이 가능하고 선언되기 전에 사용한다는 것은 위험하다.

let, const

let과 const도 호이스팅은 일어난다. 하지만 var처럼 바로 접근할 수는 없다. 메모리에 등록은 되지만 값이 들어있는 것이 아니라 초기화되지 않은 상태이기 때문에 할당문 이전까지 Temporal Dead Zone으로 막혀 있어서 접근이 불가능하다. Temporal Dead Zone은 변수는 존재하지만 초기화되기 전까지 접근할 수 없는 구간이라고 볼 수 있다.

그래서 접근하려고 하면 undefined가 아니라 ReferenceError가 발생한다.


클로저

클로저란 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다. 내부 함수가 자신이 선언될 당시의 외부 변수들을 계속 참조할 수 있는 구조를 의미한다. 외부 함수 실행이 끝난 이후에도 내부 함수가 외부 변수를 계속 참조하고 있으면 그 값은 바로 사라지지 않는다. 그래서 클로저를 통해 특정 상태를 계속 기억할 수 있다.

변수나 함수 선언 및 외부 스코프를 참조하는 구조를 기반으로 렉시컬 스코프에 따라 변수를 찾는다.

클로저는 inner 스코프와 outer 스코프로 연결되어 동작한다.

클로저 실행 결과는 무엇이고 왜 그렇게 동작할까?

나는 처음에 inner 안에 a가 선언되어 있지 않기 때문에 결과가 undefined일 것이라고 생각했다. console.log(a)를 호출하는 위치가 innerFn 안이고, inner 스코프에는 a가 없기 때문이다.
또 a를 호출하려면 outer를 호출해야 하는데 outer는 innerFn을 리턴하고 있기 때문에 outer가 끝나면 a도 사라지는 것 아닌가 생각했다.

하지만 클로저 관점으로 다시 보니 함수 스코프 범위를 보면 outer에는 var a = 10이 존재한다. var는 호이스팅이 되지만 실제 값은 할당문을 만났을 때 들어간다.

이번엔 렉시컬 스코프 체인으로 생각해보니

innerFn 내부에는 a가 없다. 그래서 자바스크립트는 바깥 스코프인 outerFn으로 올라가 a를 찾는다. outerFn의 렉시컬 환경에는 a = 10이 존재한다. 또 innerFn은 자신이 선언될 당시의 외부 환경을 기억하고 있기 때문에 outerFn의 실행이 끝난 이후에도 a를 참조할 수 있다.

그래서 실행 결과는 undefined가 아니라 10이 출력되는 것이였다. 내부 함수가 외부 함수의 렉시컬 환경을 기억하고 있기 때문에 가능한 동작이다.

profile
프론트엔드 개발자 지망생

0개의 댓글