반응형

자바스크립트 공부를 하다보면 심심치 않게 만나는 호이스팅이라는 개념...😲

들어보기도 하고 어느정도는 알고 있었지만 혼란스러운 부분이 있어서 정리가 필요했습니다!

 

먼저 간단한 자바스크립트 문법부터 보겠습니다.

 

 

함수의 호이스팅 동작

console.log("결과는? >" + test());
function test(){
    return "hi";
}

 

해당 코드의 결과는?! 아래와 같습니다!

함수 test를 호출함으로써 "hi"라는 문자열이 정상적으로 반환되어서 콘솔에 hi가 잘 찍히는걸 볼 수 있습니다.

 

실질적으로 정의된 test함수는 출력하는 콘솔로그보다 아래에 위치하지만 신기하게도 동작하는걸 볼 수 있는데 이러한 동작을 호이스팅이라고 합니다.

변수와 함수간에 동작이 조금 다른데, 이번엔 변수 동작부분을 확인해보겠습니다.

 

 

변수의 호이스팅 동작

var a = "테스트입니다~";
function test(){
    console.log("a1 >",a);
    var a = "테스트 함수에서 a변수를 재정의합니다!";
    console.log("a2 >",a);
}
test();

이번에 작성한 코드의 결과는 어떨까요? 저도 이부분에 처음에 당황을 했습니다.

 

결과는 아래와 같습니다.

예상한 결과와 같나요?

제가 처음 예상했던 답은 "테스트입니다~"가 먼저 출력되고, 재정의되었다는 문자열이 출력 될것이라고 생각했지만, 호이스팅으로 인해 전혀 다른 결과가 나왔습니다.

 

아래는 호이스팅 방식을 기반으로 해석한 코드입니다.

var a = "테스트입니다~";
function test(){
    var a;
    console.log("a1 >",a);  //undefined
    a = "테스트 함수에서 a변수를 재정의합니다!";
    console.log("a2 >",a);  //테스트 함수에서 a변수를 재정의합니다!
}
test();

해석한 코드와 기존 코드의 차이가 보이나요?

호이스팅으로 인해 test함수 최상단에 a라는 변수가 선언되었고, 콘솔로그에서 출력이 되면서 undefined라는 결과물이 나왔고, 그 이후 대입연산자를 통해 재정의라는 문자열이 대입된 것을 볼 수 있습니다.

 

이처럼 블록 구문(함수) 최상단에 변수 또는 함수명인 식별자를 최상단으로 끌어올리는 효과를 보여주는 것을 호이스팅이라고 부릅니다.

 

 

복잡한 호이스팅 동작과 전역 스코프

이번엔 복잡해진 호이스팅을 확인해보겠습니다.

var a = 1;
function outer () {
    function inner () {
        console.log(a);
        var a = 3;
        console.log(a);
        var a;
        console.log(a);
        var a = 5;
        console.log(a);
    }
    inner();
    console.log(a);
}
outer();
console.log(a);

복잡한 결과물

 

복잡하지만 차근차근 호이스팅을 분석해보겠습니다.

var a;
a = 1;
function outer () {
    function inner () {
        var a;
        var a;
        var a;

        console.log(a); //undefined
        a = 3;
        console.log(a); //3
        console.log(a); //3
        a = 5;
        console.log(a); //5
    }
    inner();
    //내부에 a변수가 없으므로 외부 스코프영역에서 a가 존재하는지 찾음
    console.log(a); //1
}
outer();
console.log(a); //1

어떤가요? 분석구문과 실제 결과와 동일한가요?

내부 스코프에 해당 변수의 선언된게 없으면 외부 스코프에서 해당 변수가 선언되었는지 확인을 합니다.

아우터부분의 a에서 그래서 1이 찍히는걸 볼 수 있습니다.

 

 

정리

다만, 변수와 함수는 또 다른 차이점이 있습니다.

- 변수는 변수명만 최상단에 정의 된 후 선언 위치에서 값이 대입되는 모습을 보여줍니다.

- 함수는 정의부 자체와 함께 최상단에 선언되는 것을 볼 수 있습니다.

 

이러한 차이점때문에 함수는 처음에 호출하여도 정의부가 잘 동작 후 출력되는것을 볼 수 있엇고, 변수는 최초 선언만 되었기 때문에, 결과 호출시 undefined와 같은 결과를 만날 수 있습니다.

 

 

다만, 함수 동작의 호이스팅에서 함수 정의 방법에 따라 달라는 결과를 볼 수 있습니다.

 

 

다양한 함수 표현방법의 호이스팅 결과

console.log(test1());
console.log(test2());
console.log(test3());

function test1(){
    return "test1";
}

var test2 = function(){
    return "test2";
}

var test3 = () => {
    return "test3";
}

function 키워드를 통해 함수를 정의하지만 변수에 함수를 대입하여 함수의 동작을 처리할 수도 있고, 화살표 함수를 통해 표현할 수도 있습니다.

다만 호이스팅 처리방식의 변수와 함수 표현식의 차이로 인해 test2, test3는 정상적으로 동작하지 않습니다.

 

아래는 동작 결과입니다.

초점을 동작하는 행위에 두지 않는다면 당연한 결과일수도 있습니다. (변수로 시작했는지, 함수로 시작했는지)

상단에 정의된 내용까지 호이스팅하는 동작은 function키워드로 정의한 부분만 동작하는 것을 볼 수 있습니다.

반응형