2015년 12월 30일 수요일

javascript: Scope of variables and functions ; 변수와 함수의 범위

Javascript: 변수와 함수의 범위

이번엔 Javascript의 변수와 함수들의 Scope(범위)에 대해서 이야기 해 보겠습니다.
기왕이면 일전에 한 포스팅(javascript: Hoisting / 호이스팅)을 먼저 한번 읽어보시는게 도움이 될것 같습니다.

( 이번 포스팅 부터는 StackEdit를 사용해서 포스팅 합니다. ^^ )

Scope이란?

Javascript에서 Scope(범위)은 함수단위로 관리됩니다. C, C++, C#, Java와 같은 언어는 Block단위로 scope이 관리되지만, 특이하게도 Javascript에서는 function단위로 scope이 관리됩니다.

참고:
블럭(Block)은 구문(Statement)들의 집합을 말합니다.
대부분의 언어에서 그렇듯, 중괄호({})로 둘러싸인 부분을 이야기 합니다.

아래의 두가지 코드를 보시죠.

// Java
public Class ScopeTest {
    public static void main( String[] args ) {
        int integer = 0;
        System.out.println( integer ); // 0

        {
            int integer = 1;
            System.out.println( integer ); // 1
        }

        System.out.println( integer ); // 0
    }
}
// Javascript
<script type="text/javascript">
    var integer = 0;
    console.log( integer ); // 0

    ( function() {
        var integer = 1;
        console.log( integer ); // 1
    } )(); // 무명 함수표현식을 사용한 1회성 실행함수

    console.log( integer ); // 0
</script>

위의 Java코드( Java를 모르셔도 상관없습니다. )를 보면 중괄호({})로 둘러싸인 코드 블럭이 보이실겁니다. 그 블럭은 별도의 Scope을 가지고 있어서 int integer라는 별도의 지역변수를 가질 수 있습니다.

반면 Javascript의 경우 Scope이 블럭단위가 아닌 function단위로 관리되기 때문에 약간 생소해 보일수도 있는 ( function() {…} )(); 표현식으로 별도의 Local Scope을 만들어 봤습니다( 이 표현식에 대해서는 다른 포스팅에서 상세히 다루도록 할게요… ).

사실 이전 포스팅(javascript: Hoisting / 호이스팅)에서 함수는 가장 처음으로 Hoisting된다고 설명을 드렸지만 조금더 정확히 말씀드리자면, 해당 Scope의 최 상단으로 끌어올려진다고 보시면 됩니다.

그럼 아래의 코드를 보시고 그 결과를 예상해 보세요.

<script type="text/javascript">
    var variable = true;
    init();
    console.log( variable );

    function init() {
        console.log( variable );
        var variable = false;
        dupInit();
        console.log( variable );

        function dupInit() {
            var variable = -100;
            console.log( variable );
        }
    }

    console.log( variable );
    dupInit();
</script>

이 코드의 실행결과는 아래와 같습니다.

Browser Console :
undefined
-100
false
true
true
[ Exception : dupInit() undefined ]

사실 위의 예제는 Hoisting을 잘 알고 계셔야 이해가 되실겁니다. 먼저 호이스팅이 되는 위치가 모두다 각 Scope의 최 상위라는것만 기억하시면 위의 결과에 대해 의문점이 해소되시리라 믿습니다. 가장 마지막 dupInit() 호출부에서 Exception이 발생하는 것에도 주목해 주세요. dupInit 함수의 scope은 init함수이므로 그 외의 범위에서는 접근할 수 없는 별도의 Local Scope이 됩니다.

위의 코드가 실제로 실행될 때는 아래와 같은 모습으로 변환이 되어 실행이 됩니다.

<script type="text/javascript">
    function init() {
        function dupInit() {
            var variable;
            variable = -100;
            console.log( variable );
        }

        var variable;
        console.log( variable );

        variable = false;

        dupInit();

        console.log( variable );
    }

    var variable;
    variable = true;

    init(); // undefined, -100, false
    console.log( variable ); // true
    console.log( variable ); // true
    dupInit(); // exception
</script>

저 역시 Java를 하다가 Javascript를 접하고 한참 지난 시점까지 이 Scope에 대한 이해없이 코딩을 해 왔습니다. 그저 Block이 기준이겠거니… 하고 말이죠. 하지만 이걸 알고, 모르고의 차이는 UI Script양이 많고 복잡한 경우에 어쩌면 밤을 안새고, 새고의 차이가 될 수도 있으니 꼭 기억해 두시기를 권장합니다.

사실 이 Scope에 대한 포스팅은 hoisting, function expression과 연관이 있어서 같이 설명을 드릴까.. 하다가 포스트 자체가 너무 길어지고 복잡해 질 것 같아서 분리했습니다. 이후에 이어질 function declaration / function expression 에 대한 내용과 함께 같이 봐 주시면 더 도움이 되리라 믿습니다.

이번 포스팅은 여기까지 하겠습니다.

Written with StackEdit.

댓글 없음:

댓글 쓰기