ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective JavaScript [12] - 변수 호이스팅
    Javascript 2016. 12. 6. 23:55



    본 게시물은 Effective Javascript의 내용을 재구성하여 작성되었음을 알립니다. 저작권 문제 발생시 게시물이 비공개 될 수 있습니다. 



    - 블록 내에서의 변수 선언은 암묵적으로 그 변수를 포함하는 함수의 맨 윗부분으로 호이스팅된다.

    - 변수의 재선언은 하나의 변수처럼 처리된다.

    - 혼란을 막기 위해 지역 변수 선언을 직접 호이스팅하는 것을 고려하라.




    자바스크립트는 어휘적 스코프를 지원하지만, 블록 단위 스코프를 지원하지 않는다. 변수 정의는 자신을 포함한 함수에 의해 지정된다. 


    function isWinner(player, others) {

        var highest = 0;

        for (var i = 0, n = others.length; i < n; i++ ) {

            var player = others[i];

            if (player.score > highest) {

                highest = player.score;

            }

        }

        return player.score > highest;

    }


    player를 반복문의 본문 안에서 선언하려는 듯 보인다. 하지만 자바스크립트 변수는 블록이 아닌 함수에 의해 스코프가 정해지기 때문에 player 내부 선언은 이미 스코프안에 선언된 변수 player 파라미터를 재선언 하는 것 뿐이다. 반복문의 이터레이션마다 동일한 변수를 덮어쓰게 된다. 그 결과, return 선언문은 player를 함수의 원래 player 인자가 아닌 마지막 요소로 보게 된다. 


    자바스크립트 변수 선언의 동작과 할당의 부분으로 나누어 이해해야 한다. 자바스크립트는 암묵적으로 함수 맨 윗부분으로 선언을 끌어올리고 할당 부분은 그 자리에 그대로 둔다. 변수는 전체 함수의 스코프 안에 있지만 실제로 var 선언문이 나타난 곳에서만 할당되는 것이다. 




    호이스팅은 변수를 재선언할 때 혼란을 초래할 수 있다. 동일한 함수 내에서 같은 변수를 여러 번 정의하는 것은 허용되지 않는다. 


    function trimSections(header, body, footer) {

        for ( var i = 0, n = header.length; i < n; i++ ) {

            header[i] = header[i].trim();

        }

        for (var i =0, n = body.length; i < n; i++) {

            body[i] = body[i].trim();

        }

        for(var i = 0, n = footer.length; i < n; i++) {

            footer[i] = footer[i].trim();

        }

    }


    trimSections 함수는 여섯 개의 지역번수(i 3개, n 3개)를 선언하지만 호이스팅으로 오직 2개만 선언되었다. 호이스팅 된 이후에는 trimSections 함수는 다음과 같이 쓰여진 셈이다.



    function trimSections(header, body, footer) {

        var i, n;

        for ( i = 0, n = header.length; i < n; i++ ) {
            header[i] = header[i].trim();
        }
        for ( i =0, n = body.length; i < n; i++) {
            body[i] = body[i].trim();
        }
        for( i = 0, n = footer.length; i < n; i++) {
            footer[i] = footer[i].trim();
        }

    }


    재선언은 별도의 변수를 나타내기 때문에, 모호함을 줄이기 위해 함수의 맨 윗부분에 모든 var 선언문을 위치시키는 방식을 선언한다. 이런 스타일은 마음에 들지 않더라도, 자바스크립트의 스코프 규칙을 이해하는 것은 코드를 읽고 쓰는데 중요하다. 


    자바스크립트에서 블록 스코프가 지원되는 예외 상황 중 하나는 바로 exception 이다. try ... catch는 exception을 잡아 변수로 바인딩하고 catch 블록 안에서만 스코프가 적용된다.


    function test ( ) {

        var x = "var", result = [ ];

        result.push(x);

        try {

            throw "exception";

        } catch (x) {

            x = "catch";

        }

        result.push(x);

        return result;

    }


    test ( );    /// ["var", "var"]



    - 블록 내에서의 변수 선언은 암묵적으로 그 변수를 포함하는 함수의 맨 윗부분으로 호이스팅된다.

    - 변수의 재선언은 하나의 변수처럼 처리된다.

    - 혼란을 막기 위해 지역 변수 선언을 직접 호이스팅하는 것을 고려하라.




    끄읕.


Designed by Tistory.