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.