JS - 호이스팅 (Hoisting) ?

김정인·2022년 12월 11일
0

JavaScript

목록 보기
2/6
post-thumbnail

📌 호이스팅 이란?


호이스팅의 정의

  • 호이스팅이란 함수 안에 있는 선언들을 모두 끌어올려 해당 함수의 유효 범위 최상단에 선언하는 것을 의마합니다. 이는 함수 정의보다 호출을 먼저 하더라도 문제없이 작동하는 유용한 특성입니다.

  • 실제 코드가 끌어올려지는 것은 아니고, JS parser 내부적으로 끌어올려 처리하는 것입니다. (따라서 실제 메모리에서 변화는 없습니다.)

호이스팅의 주의사항

  • 코드의 가독성과 유지 보수를 위해 호이스팅이 일어나지 않도록 하는 것이 바람직합니다.

  • 호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에 미리 선언하면 호이스팅으로 인한 스코프 꼬임 현상 방지가 가능합니다.



📌 호이스팅의 대상


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

  • 하지만, let / const / class 키워드를 이용한 선언문은 호이스팅이 발생하지 않은 것처럼 오류가 발생합니다. (글 하단 TDZ 참고)

  • 일반함수와 익명함수는 호이스팅 동작이 서로 다릅니다.

    • 일반 함수는 코드를 구현한 위치와 관계없이 맨 위로 끌어올려집니다.
    • 익명함수는 선언과 할당의 분리가 생기기 때문에 호출 순서에 따라 정상적으로 함수가 실행되지 않을 수 있습니다.
    • 변수에 할당된 익명함수는 변수 스코프의 규칙을 그대로 따릅니다.
function print() {
	/* 함수 선언문 */
	let result_1 = inner();
	console.log(result_1); // == string inner

	function inner() {
		return 'inner';
	}
	//

	/* 함수 표현식 */
	let result_2 = callInner();
	console.log(result_2); // TypeError: callInner is not a function

	var callInner = function () {
		return 'callInner';
	};
	//
}

print();

🤔 var의 호이스팅

  • 같은 이름의 var 변수, 함수 선언에서의 호이스팅
function calling() {
	console.log('callFunc');
}

var calling = 'callInner';

console.log(typeof calling); // == string

//--------------JS Parser 내부 호이스팅 과정--------------//

// 1. 변수 선언
var calling;

// 2. 함수 선언
function calling() {
	console.log('callFunc');
}

// 3. 변수값 할당
calling = 'callIndder';

  • 값이 할당되어 있지 않은 변수와 값이 할당되어 있는 변수에서의 호이스팅
var callingA; // 값 할당 X
var callingB = 'callingB'; // 값 할당 O

// 같은 이름의 함수들 선언
function callingA() {
	console.log('callingA Func');
}
function callingB() {
	console.log('callingB Func');
}

console.log(typeof callingA); // == function
console.log(typeof callingB); // == string

값이 할당되어 있지 않은 변수의 경우, 함수 선언문이 변수를 덮어씁니다. (= callingA)
값이 할당되어 있는 변수의 경우, 변수가 함수 선언문을 덮어 씁니다. (= callingB)

==> 예기치 못한 상황이 발생할 수 있습니다! var를 사용하지 않는 많은 이유 중 하나가 아닐까 ㅎ.ㅎ



📌 Temporal Death Zon (TDZ)


let / const / class 도 호이스팅을 합니다. 하지만 실제로 코드를 돌려보면 에러가 나오는 것을 확인할 수 있습니다. 이는 TDZ라는 개념 때문입니다.
  • TDZ란 선언 전에 변수를 사용한는 것을 비 허용하는 개념상의 공간입니다. 따라서 값을 할당하기 전에 해당 변수를 사용할 수 없도록 하여 잠재적인 버그를 줄일 수 있습니다.

  • let / const / class 구문은 TDZ의 영향을 받습니다. (var는 암묵적으로 undefined로 초기화된 상태로 JavaScript에서 읽기 때문에 영향을 받지 않음)

  • var / function / import 구문은 TDZ의 영향을 받지 않습니다.

/* TDZ */
console.log(call);
/*     */

let call = 'call Func'; // 변수의 선언 및 할당


📢 정리 !


  • 호이스팅은 함수 안에 있는 선언들을 함수 유효 범위 최상단에 끌어올려 선언하는 것
  • let, const, class 도 호이스팅을 하지만 값을 할당하기 전에 해당 변수를 사용할 수 없다는 TDZ 개념에 의해 선언 전에 변수를 사용하면 오류가 발생



🔗 참고한 글

호이스팅과 TDZ는 무엇이고 어떤 연관이 있을까요?

profile
FE 개발자

0개의 댓글