내가 보기 위해 쓰는 것/Javascript

Javascript - 호이스팅개념

do1con 2019. 10. 7. 11:53

우선 아래와 같은 코드를 보고, 어떻게 작동할지 예측해보자

 

1
2
3
4
5
if(true){
    var hey = 'hello';
}
 
console.log(hey);
cs

 

일반적인 경우 hey는 if문안에 {} 영역에서 선언되었으므로 그 밖의 영역에 있는 console.log 에서는 호출할 수 없어야 한다.

그런데 이 소스는 작동한다. 그 이유는 var hey가 호이스팅 되었기 때문이다.

위 소스는 아래처럼 호이스팅 된다.

 

1
2
3
4
5
6
7
var hey;
 
if(true){
    hey = 'hello';
}
 
console.log(hey);
cs

 

즉 호이스팅이란 선언과 할당이 분리되는 현상을 말한다. 선언은 선언된 block의 최상단으로 옮겨진다.

 

위 예시에서는 var를 사용하였다.

그리고 var는 function scope다.

function scope의 의미가 무엇일까?

var로 선언된 변수는 function을 단위로 삼아서 가장 최상단에 선언된다는 의미다.

즉 var변수의 영역 = function 블록 이며 이가 호이스팅되서 function 최상단에서 선언된다는 의미다.

말보다 소스가 빠르다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function hi (){
    if(true){
        var say = 'hi';
    }
    console.log(say);
}
 
function bye (){
    for(var i = 0; i < 10; i++){
        // nothing...
    }
    console.log(i);
}
 
if(true){
    var hello = 'hello';
}
console.log(hello);
cs

 

위와 같은 소스는 호이스팅되어서

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var hello //선언
function hi (){
    var say; //선언
    if(true){
        say = 'hi'// 할당
    }
    console.log(say);
}
 
function bye (){
    var i; // 선언
    for(i = 0; i < 10; i++){ // 
        // nothing...
    }
    console.log(i);
}
 
if(true){
    hello = 'hello'// 할당
}
console.log(hello);
cs

 

이와 같은 형태가 된다.

function을 제외한 모든 블럭을 무시하고 function을 찾아가서 최상단에서 선언된다는 의미다.

 

또 변수만 호이스팅 되는게 아니라 함수도 호이스팅 된다.

 

1
2
3
4
5
hi();
 
function hi(){
    alert('hi!');
}
cs

 

때문에 위와 같이 호출 먼저, 선언 나중에 형태의 소스도 작동하는 것이다.

위 소스도 호이스팅이 되면서

선언이 위로 올라가게 된다.

 

조금 꼬으면 이런 문제가 있다.

 

1
2
3
4
5
hi();
    
var hi = function(){
    alert('hi!');
};
cs

 

위 소스는 작동할까?

답은 작동하지 않는다.

왜냐하면 위에 설명되었듯 선언과 할당이 분리되기 때문이다.

위 소스는 아래와 같이 호이스팅된다.

 

1
2
3
4
5
6
7
var hi; // 선언
 
hi(); // 호출하였으나 지금은 hi에 아무것도 없다.
    
hi = function(){ // 할당
    alert('hi!');
};
cs

 

마지막으로 호이스팅 우선순위는 어떻게 될까?

호이스팅 우선순위는 변수 선언 > 함수 선언 > 변수 할당 순이다.

 

호이스팅에 대해서 이해했는지 스스로 테스트 해보려면 아래의 소스를 읽어보고 선언, 할당 순서를 생각해보며 결과를 생각해보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var hi = 'hi';
 
function hello(){
    alert('hello');
}
 
function bye(){
    if(true){
        var bye = 'bye';
    }
    console.log('bye');
}
 
var hungry = 'hungry';
 
console.log(hi);
console.log(hungry);
cs