본문 바로가기
가짜 개발자 Shiro/javaScript

스코프

by shiro21 2020. 1. 14.

 

스코프란?

스코프란 현재 접근할수 있는 변수들의 범위를 뜻한다.

'scope'라는 단어의 뜻을 가져와서 조금 다르게 보면, 현재 위치에서 볼 수있는 변수들의 범위를 뜻한다.

어떠한 변수가 스코프 안에 선언되었으면 해당 스코프 안에서는 변수에 접근해서 읽거나 쓸 수 있고, 스코프 밖에서는 해당 변수에 접근할 수 없다.

 

예제 ) <div>를 3개 출력하고, 각각의 <div>를 클릭했을 때 어떤 <div>를 클릭했는지 알려주는 소스이다.

 

<div id="div0">Click me! DIV 0</div>
<div id="div1">Click me! DIV 1</div>
<div id="div2">Click me! DIV 2</div>
<script>
	var i, len = 3;
    for(i=0; i<len; i++) {
    	document.getElementById("div"+i).addEventListener("clicK", function() {
        	alert("You Clicked div #" +i);
        }, false);
    }
</script>

위 코드를 실행하면 다음처럼 출력된다.

Click me! DIV 0
Click me! DIV 1
Click me! DIV 2

브라우저에 출력된 각각의 <div>를 클릭했을 때 알림창에 출력되는 결과는 다음과 같다.

 

각 <div>를 클릭 후 알림창 출력 결과

클릭 알림창 출력
Click me! div1 You clicked div #3
Click me! div2 You clicked div #3
Click me! div3 You clicked div #3

그런데 알림창 출력 결과를 보면 #3만 세번 나온다.

이와같은 문제는 스코프 때문이라고 보기보다는 스코프가 생성되고 유저되는 방법 때문에 생기는 것이다. 다른 말로는 클로저 때문에 생긴 문제다.

 

소스를 살펴보면 1~3번 줄에 있는 각각의 <div>에 대하여 클릭 이벤트 핸들러를 위한 콜백 함수가 7번 줄에 작성되어 있다. 이때 콜백 함수는 5번 줄에 선언된 변수들에 접근할 수 있는 스코프를 생성하게 된다. 이후 <div>에 클릭 이벤트가 발생해서 콜백 함수가 호출될 때도 클릭에 설정한 이벤트 핸들러의 콜백 함수는 5번 줄의 변수들에 계속 접근할 수 있는 스코프를 가지게 된다.

 

이것은 for-loop를 통해서 각각의 <div>에 순서대로 클릭 이벤트 핸들러를 부여할 때 번 줄의 변수 i가 0~3까지 증가한 뒤, 이후에 for-loop가 끝나고 나서도 계속 유지된다. 따라서 나중에 8번 줄의 alert()함수가 호출될 때 변수 i의 값은 이미 for-loop가 끝난 후의 값인 3으로 출력된다.

 

위의 for-loop를 돌 때는 별도의 스코프가 생성되지 않고 i는 글로벌 스코프에 존재한다. 그러다 addEventListener()로 콜백 함수를 설정할 때 익명 함수가 선언되면서 이때 스코프가 생성되어 스코프 체인(scope-chain)을 만들게 된다. 이후 2번째와 3번째 루프를 돌면서 div1과 div2에 대하여 클릭 이벤트에 대한 콜백 함수를 설정하고 나면 전체적인 스코프는 아래처럼 된다.

더보기
i = 2
len = 3

global scope

 

  • i = 2 <-----  div0.onclick : empty scope 
  • i = 2 <-----  div1.onclick : empty scope 
  • i = 2 <-----  div2.onclick : empty scope 

각 <div>의 클릭 이벤트에 설정되었던 콜백 함수들은 모두 같은 스코프의 변수인 i를 참조한다. 그리고 3번째 루프를 돌고 나서 마지막에 i++가 되고 나면 변수 i의 값이 3이 되면서 최종적으로 콜백 함수들은 값이 3인 i를 차모한다. 그리고 나중에 클릭 이벤트가 일어나면 8번 줄의 alert()함수는 값이 3인 i를 참조하게 되어 모두 똑같이 "#3"을 출력한다.

 

이러한 현상은 자바스크립트에서 스코프가 함수로 인해 생성되고 함수가 호출될 때도 계속 지속ㅚ어 변수들을 참조하는 특성 때문에 발생한다. 이는 자바스크립트에서 자주 발생 할 수 있는 문제로 스코프에 대해서 조금만 이해하면 쉽게 해결할 수 있다.

'가짜 개발자 Shiro > javaScript' 카테고리의 다른 글

클로저 - 2  (0) 2020.02.14
[쉬어가기] Return  (0) 2020.02.03
클로저 - 1  (0) 2020.01.22
스코프 - 3  (0) 2020.01.21
스코프 - 2  (0) 2020.01.15