호이스팅(Hoisting)

2022. 9. 22. 22:24프로그래밍 언어/JavaScript

호이스팅(Hoisting)

호이스팅은 '끌어올리기' 라는 뜻으로, 함수 또는 변수가 끌어올려져 최상단에 선언되는 현상을 말한다.

function foo() {
	console.log('foo');
}

foo(); // foo
foo(); // foo

function foo() {
	console.log('foo');
}

Java와 다르게 함수 선언 자체를 나중에 해줘도 함수를 끌어올려서(Hoist) 갖고온다.

  • 호이스팅은 JavaScript 엔진이 가지고 있는 특징이다.
  • 함수표현식과 같이 에러가 발생하는 예외가 있기 때문에 신중히 사용해야 한다.
  • 호이스팅이 발생하는 코드는 이해하기 어려워지고 > 유지보수가 힘들어지기 때문에 > 호이스팅 현상은 방지하는 것이 좋다.

 

호이스팅 적용 대상

호이스팅은 var 변수 선언과 함수 선언문에서만 발생한다.

함수 할당이나 let/const 변수에서는 발생하지 않는다.

var foo = 'foo' 호이스팅 발생
let foo = 'foo' 호이스팅 미발생
function foo() { ... } 호이스팅 발생
var foo = function() { ... } 호이스팅 미발생

 

 

var vs let/const

console.log('test');
var foo = 'foo'; // var 변수
let foo2 = 'foo2'; // let 변수
/* 호이스팅 결과 */
var foo; // 호이스팅 발생: 변수 선언
console.log('test');
foo  = 'foo'; // 할당
let foo2 = 'foo2'; // 호이스팅 미발생: let 변수

ES6에서 지원하는 let/const는 호이스팅이 발생하지 않는다.

 

 

함수선언문 vs 함수표현식

foo();
foo2();

function foo() { // 함수선언문
	console.log('foo');
}

var foo2 = function() { // 함수표현식
	console.log('foo2');
}
/* 호이스팅 결과 */
var foo2; // 호이스팅 발생: 변수 선언

function foo() { // 호이스팅 발생: 함수선언문
	console.log('foo');
}

foo(); // 통과: 호이스팅으로 인해 선언된 함수. // foo
foo2(); // 에러: 선언되지 않은 함수. // foo2 is not a function

foo2 = function() { // 함수 할당: 함수표현식
	console.log('foo2');
}

 

 

호이스팅 우선순위

var bar = 'bar';

function foo() {
	console.log('foo');
}

function foo2() {
	console.log('foo2');
}

var bar2 = 'bar2';

console.log(typeof foo);
console.log(typeof foo2);
/* 호이스팅 결과 */
// 1. 변수 선언
var bar;
var bar2;

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

function foo2() {
	console.log('foo2');
}

// 3. 변수값 할당
bar = 'bar';
bar2 = 'bar2';

console.log(typeof foo); // string
console.log(typeof foo2); // string

JavaScript 파서는 함수보다 변수를 더 우위로 판단하여 최상단에 위치시킨다.

 

 

호이스팅 방지

  • 변수와 함수를 가급적 상단부에서 선언한다.
  • 변수를 먼저 선언한 다음 함수를 선언한다.
    JavaScript 파서는 함수보다 변수를 더 우위로 판단하여 최상단에 위치시킨다.
  • var 대신 let/const 를 사용한다.
    ES6에서 지원하는 let/const는 호이스팅이 발생하지 않는다.

 


Reference

 

 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

이벤트 전달 방식  (0) 2022.09.26
클로저(Closure)  (0) 2022.09.22
스코프(Scope)  (0) 2022.09.22
TypeScript 타입 어디까지 지정해줘야 할까  (0) 2022.08.13
location.href와 location.replace의 차이  (0) 2021.01.18