💡 스코프에 대해 미리 알고 계시면 이 글의 내용을 더 쉽게 이해하실 수 있습니다.
자바스크립트를 배우다 보면 변수를 선언하기 전에 사용했는데 에러가 나지 않거나, 예상과 다른 결과가 나와서 “어? 이게 왜 이렇게 동작하지?“라고 당황한 적이 있으실 거예요.
저도 처음 자바스크립트를 배울 때 이런 상황을 마주했는데, 특히 var
로 선언한 변수가 선언 전에도 undefined
로 출력되는 걸 보고 완전히 혼란스러웠어요. 그런데 호이스팅의 개념을 정확히 알고 나니, 자바스크립트 코드의 동작을 예측할 수 있게 되었고 더 안전한 코드를 작성할 수 있게 되었습니다.
이 글에서는 자바스크립트 호이스팅의 모든 것을 명확하게 알려드릴게요. var
, let
, const
의 호이스팅 차이점부터 TDZ(Temporal Dead Zone)라는 중요한 개념까지, 어려운 이론보다는 직접 손으로 따라 할 수 있는 실제 코드 예제를 중심으로 설명해 드리겠습니다.
호이스팅의 기본 개념부터 실무에서 자주 만나는 함정과 해결법까지, 실제 코드 예제와 함께 단계별로 살펴봅니다. 이 글을 다 읽고 나면 “왜 이 코드는 에러가 나지 않을까?“라는 의문이 완전히 해결될 거예요.
자바스크립트 호이스팅 핵심 정의
자바스크립트 호이스팅이란?
호이스팅(Hoisting)은 변수와 함수 선언이 코드 실행 전에 해당 스코프의 맨 위로 “끌어올려지는” 것처럼 동작하는 자바스크립트의 특성입니다. 정확히는 자바스크립트 엔진이 코드를 실행하기 전에 변수와 함수의 이름을 메모리에 미리 등록하는 과정으로, 선언만 끌어올려지고 할당(값 대입)은 원래 위치에서 이루어집니다.
왜 호이스팅을 알아야 할까요?
실제 프로젝트에서는 코드가 수백, 수천 줄이 되는데, 호이스팅을 모르면 예상치 못한 버그가 발생할 수 있어요. 특히 React 같은 프레임워크를 배우기 전에 호이스팅을 확실히 이해해 두면, 컴포넌트 내에서 변수를 다룰 때 훨씬 안전하게 코드를 작성할 수 있습니다.
var로 선언한 변수의 호이스팅 동작
var
로 선언한 변수는 호이스팅 되면서 undefined
로 자동 초기화됩니다. 이게 다른 언어와 가장 큰 차이점이에요.
var 호이스팅의 기본 동작
|
|
위 코드는 실제로 다음과 같이 동작합니다.
|
|
함수 내에서 var 호이스팅
|
|
var의 특징:
- 선언과 초기화가 동시에 발생 - 호이스팅 시점에
undefined
로 초기화됩니다. - 함수 스코프 - 블록 내부에서 선언해도 함수 전체에서 접근 가능합니다.
- 재선언 허용 - 같은 이름으로 여러 번 선언할 수 있습니다.
let과 const의 호이스팅과 TDZ
let
과 const
도 호이스팅 되지만, var
와는 다르게 TDZ(Temporal Dead Zone) 때문에 선언 전에는 접근할 수 없어요.
let과 const의 기본 동작
|
|
TDZ(Temporal Dead Zone)란?
TDZ는 let
과 const
변수가 선언되기 전까지 접근할 수 없는 구간을 말합니다. 이 구간에서는 변수가 마치 존재하지 않는 것처럼 동작해요.
|
|
TDZ의 범위와 섀도잉
|
|
let과 const의 특징:
- 선언은 되지만 초기화는 안 됨 - 선언문에 도달해야 초기화됩니다.
- 블록 스코프 - 선언된 블록 내에서만 유효합니다.
- 재선언 금지 - 같은 스코프에서 중복으로 선언할 수 없습니다.
함수 호이스팅의 특별한 동작
함수는 변수와 다르게 호이스팅 동작이 특별해요. 함수 선언문과 함수 표현식의 차이를 알아보겠습니다.
함수 선언문 호이스팅
|
|
함수 표현식 호이스팅
|
|
화살표 함수와 호이스팅
|
|
블록 스코프에서의 호이스팅 동작
let
과 const
는 자신이 선언된 블록 스코프에서만 호이스팅 됩니다. 이 부분이 가장 헷갈리는 부분인데, 실제 코드로 살펴볼게요.
블록별 독립적 호이스팅
|
|
실무에서 자주 하는 실수
|
|
실무에서 주의해야 할 호이스팅 함정들
제가 실무를 하면서 직접 겪었거나, 팀원들이 자주 하는 실수를 정리해 봤어요.
에러 발생 시 실행 완전 중단
|
|
ReferenceError
가 발생하면 그 지점에서 실행이 완전히 중단됩니다. 이는 실무에서 매우 중요한 포인트예요.
var의 블록 스코프 무시 문제
|
|
현대 자바스크립트 모범 사례
var
대신let
과const
사용하기
|
|
- 변수는 사용하기 전에 선언하기
|
|
- 적절한 스코프 범위 설정하기
|
|
- ESLint 같은 도구로 잠재적 문제 미리 찾기
var vs let vs const 호이스팅 비교표
특성 | var | let | const |
---|---|---|---|
호이스팅 여부 | ✅ 됨 | ✅ 됨 | ✅ 됨 |
초기화 시점 | 선언과 동시 (undefined ) | 선언문 도달 시 | 선언문 도달 시 |
TDZ 존재 | ❌ 없음 | ✅ 있음 | ✅ 있음 |
스코프 | 함수 스코프 | 블록 스코프 | 블록 스코프 |
재선언 가능 | ✅ 가능 | ❌ 불가능 | ❌ 불가능 |
재할당 가능 | ✅ 가능 | ✅ 가능 | ❌ 불가능 |
선언 전 접근 | undefined 반환 | ReferenceError | ReferenceError |
자주 묻는 질문들 (FAQ)
Q1. 호이스팅이 일어나는 이유가 뭔가요?
호이스팅은 자바스크립트 엔진이 코드를 실행하기 전에, 컴파일 단계에서 변수와 함수 선언을 미리 메모리에 등록하기 때문에 발생합니다. 이 과정은 자바스크립트의 실행 컨텍스트(Execution Context, 코드가 실행되는 환경을 관리하는 영역)가 만들어질 때 함께 진행돼요.
저도 이 개념을 처음 배웠을 때는 “왜 굳이 이렇게 복잡하게 동작할까?“라는 생각이 들었어요. 그런데 알고 보니, 자바스크립트 엔진이 코드를 더 빠르게 실행하고 최적화하기 위해 이런 구조를 선택한 거더라고요.
특히 함수 선언문은 미리 메모리에 등록되어 있기 때문에, 호출보다 나중에 선언해도 문제없이 실행할 수 있다는 장점이 있어요. 이게 바로 호이스팅 덕분입니다!
Q2. TDZ는 왜 만들어졌나요?
TDZ(Temporal Dead Zone)는 let
과 const
가 ES6에서 도입되면서, 더 안전한 코드를 작성할 수 있도록 하기 위해 생긴 개념이에요. 기존에 쓰이던 var
는 선언 전에 접근해도 에러가 나지 않아서, 예측하기 어려운 버그가 자주 발생했거든요.
제 경험상, TDZ 덕분에 변수를 실수로 잘못 사용하는 경우가 확실히 줄어들었어요. 선언 전에 접근하면 바로 에러가 나기 때문에, 문제를 더 빨리 찾아낼 수 있어요.
Q3. 함수 선언문과 함수 표현식 중 어떤 걸 써야 하나요?
상황에 따라 다르지만, 최근에는 함수 표현식(특히 화살표 함수)을 더 많이 사용하는 추세예요.
|
|
저는 컴포넌트 내부의 작은 함수들은 화살표 함수를, 재사용성이 높은 유틸 함수는 함수 선언문을 사용하는 편이에요.
Q4. React에서 호이스팅은 어떻게 영향을 주나요?
React 컴포넌트 내에서도 자바스크립트 호이스팅 규칙이 그대로 적용돼요. 특히 useState
나 useEffect
같은 Hook을 사용할 때 변수 스코프를 잘 관리해야 해요.
|
|
Q5. 호이스팅을 완전히 피할 수 있는 방법이 있나요?
완전히 피할 수는 없지만, 좋은 코딩 습관으로 호이스팅으로 인한 문제를 최소화할 수 있어요.
- 변수는 사용하기 직전에 선언하기
const
를 우선 사용하고, 변경이 필요할 때만let
사용하기var
는 사용하지 않기- ESLint 같은 도구로 잠재적 문제 미리 찾기
마무리: 호이스팅으로 더 나은 자바스크립트 개발자 되기
핵심 요약:
- 호이스팅은 선언만 끌어올리고 할당은 원래 위치에서 발생합니다.
var
는undefined
로 초기화되지만,let
/const
는 TDZ로 보호됩니다.- 함수 선언문은 완전히 호이스팅되어 어디서든 호출 가능합니다.
- 블록 스코프에서
let
/const
는 해당 블록에서만 호이스팅됩니다. - 현대 자바스크립트에서는
const
→let
→var
순으로 사용하는 것이 좋습니다.
오늘 배운 호이스팅 개념으로 간단한 사용자 로그인 상태 관리 함수를 만들어보세요. const
와 let
을 적절히 활용하면서 블록 스코프도 고려해 보면 좋을 것 같아요. 실제로 코드를 작성하면서 호이스팅 동작을 체험해 보는 게 가장 빠른 학습 방법이거든요.
다음 글에서는 자바스크립트 클로저(Closure)에 대해 다뤄보겠습니다. 호이스팅과 스코프를 이해하셨다면 클로저도 쉽게 이해하실 수 있을 거예요!
여러분의 자바스크립트 호이스팅 학습 경험은 어떠셨나요? 어려웠던 부분이나 추가로 궁금한 점이 있다면 댓글로 공유해주세요! 실무에서 호이스팅 때문에 겪었던 경험담도 환영해요. 😊