목표
- 호이스팅(Hoisting)이란 무엇인지 이해한다.
- 함수선언문과 함수표현식에서의 호이스팅 차이를 이해한다.
- let/const와 var 변수 선언에서의 호이스팅 예시 - 같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅에 대해 이해한다.
호이스팅(Hoisting)의 개념
- 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
- 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
- 함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
- 유효 범위: 함수 블록 {} 안에서 유효하다.
- 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
- 실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
- 실제 메모리에서는 변화가 없다.
*** 호이스팅은 변수를 선언하고 초기화했을 때, 선언 부분이 최상단으로 끌어올려지는 현상을 말한다.
var의 경우 변수를 선언하고 초기화하는 과정이 동시에 일어나서 호이스팅이 발생한다.
반면 let/const 의 경우 선언과 초기화 단계가 동시에 일어나지 않는다.
실행 시점에서 실제 선언부를 만날 때 초기화가 이뤄진다. 그 사이의 시간을 TDZ(Temporary Dead Zone)이라고 한다. 즉 실행 컨텍스트에 변수가 선언은 되었으나 메모리가 할당되지 않아 ReferenceError가 발생한다. 함수 호이스팅은 선언문에서 발생한다. 선언된 함수는 상단에서 참조, 호출이 가능하다. 함수 표현식은 결국 변수에 할당하는 모습이라 변수 호이스팅의 사례로 볼 수 있다.
(변수 선언 3단계: 선언 -> 초기화 -> 할당)
호이스팅의 대상
- var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
- var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
- let / const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
- (변수 선언 3단계: 선언 -> 초기화 -> 할당)
- 예시 ( var 변수 vs let / const 변수 )
console.log("hello");
var myname = "HEEE"; // var 변수
let myname2 = "HEEE2"; // let 변수
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
var myname; // [Hoisting] "선언"
console.log("hello");
myname = "HEEE"; // "할당"
let myname2 = "HEEE2"; // [Hoisting] 발생 X
- 예시 ( 함수선언문 vs 함수표현식 )
foo();
foo2();
function foo() { // 함수선언문
console.log("hello");
}
var foo2 = function() { // 함수표현식
console.log("hello2");
}
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
var foo2; // [Hoisting] 함수표현식의 변수값 "선언"
function foo() { // [Hoisting] 함수선언문
console.log("hello");
}
foo();
foo2(); // ERROR!!
foo2 = function() {
console.log("hello2");
}
- 호이스팅은 함수선언문과 함수표현식에서 서로 다르게 동작하기 때문에 주의해야 한다.
- 함수에 할당된 함수표현식은 끌어 올려지지 않기 때문에 이때는 변수의 스코프 규칙을 그대로 따른다.
호이스팅 우선순위
같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅
- 변수 선언이 함수 선언보다 위로 끌어 올려진다.
var myName = "hi";
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
var yourName = "bye";
console.log(typeof myName);
console.log(typeof yourName);
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
// 1. [Hoisting] 변수값 선언
var myName;
var yourName;
// 2. [Hoisting] 함수선언문
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
// 3. 변수값 할당
myName = "hi";
yourName = "bye";
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "string"
var myName = "Heee"; // 값 할당
var yourName; // 값 할당 X
function myName() { // 같은 이름의 함수 선언
console.log("myName Function");
}
function yourName() { // 같은 이름의 함수 선언
console.log("yourName Function");
}
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "function"
Tip: 호이스팅 사용 시 주의
- 코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
- var를 쓰면 혼란스럽고 쓸모없는 코드가 생길 수 있다
출처: https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
'개발 지식' 카테고리의 다른 글
this의 용법을 아는대로 설명하시오 (0) | 2022.11.11 |
---|---|
GET, POST 방식 차이 (0) | 2022.11.09 |
함수선언문과 함수표현식의 차이 (0) | 2022.11.03 |
클로저는 무엇인가요? 원리와 왜 사용하는지 설명해 주세요. (0) | 2022.11.03 |
브라우저는 어떻게 동작하는가? (0) | 2022.11.03 |
댓글