함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
*호이스팅은 함수선언문과 함수표현식에서 서로 다르게 동작하기 때문에 주의해야 한다.
foo();
foo2();
function foo(){
console.log("hello")
}
var foo2 = function(){
console.log("hello2");
}
//hello
//TypeError: foo2 is not a function
*변수에 할당된 함수표현식은 끌어 올려지지 않기 때문에 이때는 변수의 스코프 규칙을 그대로 따른다.
var foo2; // 호이스팅. 함수표현식의 변수값 "선언"
function foo() {
console.log("hello")
}
foo();
foo2(); // Error
foo2 = function(){
console.log("hello2");
}
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(); // 함수 호출
위 함수의 JS Parser 호이스팅 결과.
function printName(firstName){
var result; // 호이스팅. var 변수 "선언"
function inner() { // 호이스팅. 함수선언문
return "inner value";
}
result = inner(); // 할당
console.log(typeof inner); // "function"
console.log("name is" + result); // "name is inner value"
}
printName();
function printName(firstname){
var inner = function(){
return "inner value";
}
var result = inner();
console.log("name is" + result);
}
printName(); "name is inner value"
function printName(firstname){
var inner;
var result;
inner = function(){
return "inner value";
}
result = inner();
console.log("name is " + result);
}
printName();
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 printName(firstname){
var inner; // 호이스팅. 함수 표현식의 변수값 "선언"
console.log(inner); // "undefined"
var result = inner(); // Error !
console.log("name is" + result);
inner = function(){
return "inner value";
}
}
printName(); // TypeError : inner is not a function
function printName(firstname){ // 함수선언문
console.log(inner); // Error !
let result = inner();
console.log("name is" + result);
let inner = function(){ // 함수표현식
return "inner value";
}
}
printName(); // RefereneceError : inner is not defined
같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅
var myname = "marvel";
function myName(){
console.log("superman");
}
function yourName(){
console.log("batman");
}
var yourName() = "ironman";
console.log(typeof myName);
console.log(typeof yourName);
호이스팅 결과.
// 1. 호이스팅 변수값 선언.
var myName;
var yourName;
// 2. 호이스팅 함수선언문
function myName(){
console.log("superman");
}
function yourName(){
console.log("batman");
}
// 3. 변수값 할당.
myName = "marvel";
yourName = "ironman";
console.log(typeof myName); // "string"
console.log(typeof yourName); // "string"
값이 할당되어 있지 않은 변수와 값이 할당되어 있는 변수에서의 호이스팅.
var myName = "ironman"; // 값 할당
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"
-> 값이 할당되어 있지 않은 변수인 경우 , 함수선언문이 변수를 덮어쓴다.
-> 값이 할당되어 있는 변수의 경우, 변수가 함수선언문을 덮어쓴다.