호이스팅(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 |