minzzl
[Javascript] 호이스팅 본문
호이스팅
함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것
자바스크립트에서 호이스팅이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당 하는 것을 의미합니다. 쉽게 말해, 어디에 선언했는지는 상관 없이 항상 제일 위로 선언을 끌어올려 주는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined 로 변수를 초기화 합니다. 반면 let과 const로 선언한 변수의 경우 호스팅 시 변수를 초기화 하지 않습니다.
호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행하여 변수가 초기화 됨을 주의하세요.
함수 선언문과 함수 표현식에서의 호이스팅
(1) 함수 선언문에서의 호이스팅
함수 선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어올려집니다. 즉, 해당 예제에서는 함수선언문이 아래에 있어도 printName 함수 내에서 inner를 function으로 인식하기 때문에 오류가 발생하지 않습니다.
/* 정상 출력 */
function printName(firstname) { // 함수선언문
var result = inner(); // "선언 및 할당"
console.log(typeof inner); // > "function"
console.log("name is " + result); // > "name is inner value"
function inner() { // 함수선언문
return "inner value";
}
}
printName(); // 함수 호출
(2) 함수 표현식에서의 호이스팅
함수 표현식은 함수선언문과 달리 선언과 호출 선서에 따라서 정상적으로 함수가 실행되지 않을 수 있습니다.
a. 함수 표현식의 선언이 호출보다 위에 있는 경우
/* 정상 */
function printName(firstname) { // 함수선언문
var inner = function() { // 함수표현식
return "inner value";
}
var result = inner(); // 함수 "호출"
console.log("name is " + result);
}
printName(); // > "name is inner value"
b. 함수 표현식의 선언이 호출보다 아래에 있는 경우
/* 오류 */
function printName(firstname) { // 함수선언문
console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
var result = inner(); // ERROR!!
console.log("name is " + result);
var inner = function() { // 함수표현식
return "inner value";
}
}
printName(); // > TypeError: inner is not a function
자바스크립트는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당합니다. 덕분에 함수를 호출하는 코드를 함수 선언보다 앞서 배치할 수 있습니다.
function catName(name) {
console.log("제 고양이의 이름은 " + name + "입니다");
}
catName("호랑이");
/*
결과: "제 고양이의 이름은 호랑이입니다"
*/
위의 코드 조각이 일반적으로 코드를 작성하는 순서라면, 함수를 선언하기 전에 먼저 호출했을 때의 예제도 보겠습니다.
catName("클로이");
function catName(name) {
console.log("제 고양이의 이름은 " + name + "입니다");
}
/*
결과: "제 고양이의 이름은 클로이입니다"
*/
함수 호출이 함수 자체보다 앞서 존재하지만, 그럼에도 불구하고 이 코드 역시 동작합니다. 이것이 자바스크립트에서 실행 맥락이 동작하는 방식입니다.
호이스팅은 다른 자료형과 변수에도 잘 작동합니다. 변수를 선언하기 전에 먼저 초기화 하고 사용할 수 있는 것입니다.
호이스팅 대상
자바스크립트는 초기화를 제외한 선언만 호이스팅합니다. 변수를 먼저 사용하고 후에 선언 및 초기화가 나타나면, 사용하는 시점의 변수는 기본 초기화 상태(var 선언시 undefinded, 그 외에는 초기화하지 않음)입니다. 예를 들어
console.log(num); // 호이스팅한 var 선언으로 인해 undefined 출력
var num; // 선언
num = 6; // 초기화
반면, 다음 예제는 선언 없이 초기화만 존재합니다. 따라서 호이스팅도 없고, 변수를 읽으려는 시도에서는 ReferenceError 예외가 발생합니다.
console.log(num); // ReferenceError
num = 6; // 초기화
다음은 호이스팅을 보이는 더 많은 예제입니다.
// 예제 1
// y만 호이스팅 대상
x = 1; // x 초기화. x를 선언하지 않은 경우 선언. 그러나 명령문에 var가 없으므로 호이스팅이 발생하지 않음
console.log(x + " " + y); // '1 undefined'
// JavaScript는 선언만 호이스팅하므로, 윗줄의 y는 undefined
var y = 2; // y를 선언하고 초기화
// 예제 2
// 호이스팅은 없지만, 변수 초기화는 (아직 하지 않은 경우) 변수 선언까지 병행하므로 변수를 사용할 수 있음
a = '크랜'; // a 초기화
b = '베리'; // b 초기화
console.log(a + "" + b); // '크랜베리'
let과 const 호이스팅
let과 const로 선언한 변수도 호이스팅 대상이지만, var 과 달리 호이스팅 시 undefined로 변수를 초기화하지는 않습니다. 따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외가 발생합니다.
호이스팅 우선 순위
같은 이름의 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)의 결과는 아래와 같다.
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"
* 아래의 글을 참고하여 작성하였습니다.
https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
[JavaScript] 호이스팅(Hoisting)이란 - Heee's Development Blog
Step by step goes a long way.
gmlwjd9405.github.io
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
호이스팅 - 용어 사전 | MDN
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다
developer.mozilla.org
'프로젝트 > 자바스크립트' 카테고리의 다른 글
[Javascript] Class vs Object (0) | 2022.10.08 |
---|---|
[Javascript] operator와 loop,if (0) | 2022.10.08 |
[Javascript] 함수 선언문 vs 함수 표현식 (0) | 2022.10.08 |
[Javascript] 데이터타입 let var const (1) | 2022.10.07 |