티스토리 뷰

▶호이스팅(Hoisting)

스코프의 개념과 렉시컬 스코프 규칙에 대해 어느 정도 정리가 되었을 것입니다.

이제 스코프 안에서 변수를 선언하였을 때 발생하는 호이스팅(Hoisting)이라는 동작에 대해 좀 더 자세히 알아봅시다.

호이스팅선언문이 스코프 내의 가장 최상단으로 끌어올려지는 것을 의미합니다.

console.log(a); // Undefined
var a = 1;

전역 스코프 내의 변수 a를 선언하기 전에 console.log() 메서드에서 참조하였습니다.

선언하기 전에 접근하였으니 "ReferenceError: a is not defined"에러가 발생할 것 같지만, 예상과 달리 정상적으로 실행되어 undefined가 출력됩니다.

왜 이런 결과가 나오는 것일까요?

답은 호이스팅입니다.

선언문 var a;가 전역 스코프의 최상단으로 끌어올려지기 때문에 선언되기 이전에 참조할 수 있는 것입니다.

호이스팅을 변수 생성 과정과 함께 살펴보겠습니다.

자바스크립트의 변수는 세 가지 단계로 나누어 생성됩니다.

 

- 선언 : 스코프에서 변수를 선언합니다.

- 초기화 : 변수의 값을 undefined로 초기화하며, 실제로 변수에 접근 가능한 단계입니다.

- 할당 : 할당문을 만나면 변수에 실제 값을 할당합니다.

 

var 키워드로 선언한 변수는 선언과 초기화 단계를 한 번에 실행합니다.

그리고 이 두 단계는 스코프의 최상단으로 끌어올려져 실행됩니다.

따라서 선언하기 전에 변수에 접근하여도 이미 초기화가 되어 접근이 가능한 것입니다.

이러한 동작을 호이스팅이라고 합니다.

 

앞의 예제 코드는 호이스팅이 발생하여 다음 코드처럼 처리됩니다.

// 스코프의 최상단에서 변수 a의 선언과 초기화가 한 번에 실행됩니다.
var a;
console.log(a); // undefined
a = 1;

 

1) 스코프별로 동작하는 호이스팅

호이스팅은 스코프별로 동작합니다.

전역 스코프가 아닌 함수 내에 선언된 변수는 함수 스코프 안에서 호이스팅이 발생합니다.

function foo() {
	console.log(a);
   	var a = 1;
}

위의 코드는 아래 코드처럼 처리됩니다.

function foo() {
	var a ;
   	console.log(a);
   	a = 1;
}

▷let과  const

let과 const 키워드로 선언한 변수는 var 키워드와 다르게 선언과 초기화 단계가 분리되어 실행됩니다.

선언 단계는 스코프의 최상단으로 끌어올려져 실행되지만, 초기화 단계는 선언문을 만나면 실행됩니다.

그리고 초기화 단계 이전에 변수에 접근하려고 하면 ReferenceError가 발생합니다.

선언 단계가 실행되는 스코프의 최상단부터 초기화 단계를 실행하는 선언문이 나오기 전까지는 변수에 접근할 수 없습니다.

그리고 이 구간을 Temporal Dead Zone(TDZ)이라고 부릅니다.

let과 const의 변수 생성 과정과 TDZ

console.log(a); // Uncaught ReferenceError: a is not defined
let a = 1;

let 키워드로 선언된 변수 a는 초기화 단계를 실행하기 전인 TDZ 구간에서 참조하였기 때문에 ReferenceError가 발생합니다.

  • 선언은 끌어올려진다.

let과 const 키워드로 선언한 변수의 초기화는 선언문을 만나는 시점에 실행되지만 선언 단계는 스코프의 최상단으로 끌어올려져 실행됩니다.

let a = 1;

function foo() {
	console.log(a); // Uncaught ReferenceError: Cannot acess 'a' before initialization
   	let a = 1;
}
foo();

foo() 함수의 실행 결과로 전역 변수 a의 값이 출력될 것 같지만 에러가 발생합니다.

foo() 함수의 지역 변수 a의 선언 단계는 foo() 함수 스코프의 최상단에서 실행됩니다.

그리고 이 지점부터 선언문을 만나기 전까지 TDZ 구간이 생성됩니다.

이 TDZ 구간에서 console.log() 메서드를 호출하여 변수 a에 접근하였기 때문에 ReferenceError가 발생하는 것입니다.

 

[NOTE]

foo() 함수 내에서 전역 변수 a가 아닌 함수 내의 지역 변수 a를 머너 참조하는 이유는 스코프 체인에 따라 가장 안쪽의 스코프부터 검색하기 때문입니다.

 

2) 함수 선언문의 호이스팅

함수 선언문 역시 선언문이기 때문에 호이스팅이 발생합니다.

다만, 함수 선언문의 호이스팅은 함수 선언, 초기화, 할당 세 가지 단계가 모두 동시에 스코프 최상단에서 실행됩니다.

그렇기 때문에 어느 위치에서든 함수를 호출할 수 있습니다.

consolo.log(a()); // 1

function a() {
	console.log(1);
}

함수 선언문이 아닌 함수 표현식은 변수의 호이스팅 규칙에 따라 동작합니다.

 


여기까지 자바스크립트 호이스팅에 대해 알아보았습니다 :)

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함