티스토리 뷰

JavaScript

JS - 호이스팅 (Hoisting) ?

김관장 2022. 7. 5. 17:30

1. 호이스팅 이란?

   1-1. 호이스팅 정의

 

  • 호이스팅이란 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수의 유효 범위 최상단에 선언하는 것을 의미합니다. 이는 함수 정의보다 호출을 먼저 하더라도 문제없이 작동되는 유용한 특성입니다.
  • 실제로 코드가 끌어올려지는 것은 아니고, JS parser 내부적으로 끌어올려 처리하는 것입니다.
    (=> 따라서 실제 메모리에서 변화는 없음)
  • 유효한 블록 스코프내의 할당이 아닌 선언만으로도 최상위로 이끌어 올린 후 필요할 때마다 사용하는 것을 말합니다.

   1-2. 호이스팅 사용 주의사항

 

  • 코드의 가독성과 유지 보수를 위해 호이스팅이 일어나지 않도록 호이스팅이 일어나지 않도록 합니다.
    호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에 선언하면, 호이스팅으로 인한 스코프 꼬임 현상 방지가 가능합니다. 
  • var를 쓰면 쓸모없고 복잡한 코드가 생길 수 있습니다. var에 대한 충분한 이해를 하기 전엔 사용하지 않는 것을 추천합니다!

2. 호이스팅의 대상

  • 자바스크립트의 모든 선언에는 호이스팅이 일어납니다.
  • let / const / class 키워드를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작합니다. (글 하단 TDZ 참고)
  • var로 선언한 변수의 경우 호이스팅 시 변수의 값을 undefined로 초기화합니다.

   2-1. 함수 선언문과 표현식에서의 호이스팅

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();
  • 함수 선언문은 코드를 구현한 위치와 관계없이 맨 위로 끌어올려집니다.
  • 함수 표현식은 선언과 할당의 분리가 생기기 때문에 호출 순서에 따라 정상적으로 함수가 실행되지 않을 수 있습니다. 변수에 할당된 함수 표현식은 변수 스코프의 규칙을 그대로 따릅니다.

3. 호이스팅 우선순위

   3 - 1. 같은 이름의 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';
  • 변수 선언 -> 함수 선언 -> 변수 할당 순 (변수 선언이 함수 선언보다 위로 끌어올려집니다.)

   3 - 2. 값이 할당되어 있지 않은 변수와 값이 할당되어 있는 변수에서의 호이스팅

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)

4. Temporal Death Zon (TDZ)

let / const / class 도 호이스팅을 합니다. 하지만 에러가 나오는 것을 확인할 수 있습니다. 이는 TDZ 때문입니다.

 

  • TDZ란 선언 전에 변수를 사용하는 것을 비 허용하는 개념상의 공간입니다. 따라서 값을 할당하기 전에는 해당 변수를 사용할 수 없도록 하여 잠재적인 버그를 줄일 수 있습니다.
  • let 변수, const 변수, class 구문은 TDZ의 영향을 받습니다. (var는 암묵적으로 undefined로 초기화된 상태로 JS에서 읽기 때문에 영향을 받지 않음)
  • var 변수, function 선언, import 구문은 TDZ의 영향을 받지 않습니다.
/* TDZ */
console.log(call);
/*     */

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

console.log(call); // 사용 가능 == call Func

🤔  정리 !

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

 

 

🔗 참고한 글

 

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

호이스팅 ? > 함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 스코프의 최상단에 선언 하는 것을 말합니다. 호이스팅의 대상 var 변수 선언과 함수 선언문에서만 호이스팅이 일어납니

velog.io

'JavaScript' 카테고리의 다른 글

JS - generator 함수와 yield  (0) 2022.07.12
JS - JSON ?  (0) 2022.07.09
JS - Lodash ?  (3) 2022.07.04
JS - async / await 병목 현상 (feat. promise.all)  (0) 2022.05.20
JS - 복사한 값, 붙여넣기 이벤트  (0) 2022.05.12
댓글