JavaScript

유효범위

유효범위(Scope)는 변수의 수명을 의미한다. 아래의 예제를 보자. 결과는 global이다.

var vscope = 'global';
function fscope(){
	alert(vscope);
}
fscope();

함수 밖에서 변수를 선언하면 그 변수는 전역변수가 된다. 전역변수는 에플리케이션 전역에서 접근이 가능한 변수다. 다시 말해서 어떤 함수 안에서도 그 변수에 접근 할 수 있다. 그렇기 때문에 함수 fscope 내에서 vscope를 호출 했을 때 함수 밖에서 선언된 vscope의 값 global이 반환된 것이다. 아래 예제를 보자. 결과는 '함수안 local'과 '함수밖 global'이 출력된다.

var vscope = 'global';
function fscope(){
    var vscope = 'local';
	alert('함수안 '+vscope);
}
fscope();
alert('함수밖 '+vscope);

즉 함수 안에서 변수 vscope을 조회(4행) 했을 때 함수 내에서 선언한 지역변수 vscope(3행)의 값인 local이 사용되었다. 하지만 함수 밖에서 vscope를 호출(7행) 했을 때는 전역변수 vscope(1행)의 값인 global이 사용된 것이다. 즉 지역변수의 유효범위는 함수 안이고, 전역변수의 유효범위는 에플리케이션 전역인데, 같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 지역변수가 우선한다는 것을 알 수 있다. 아래 예제를 보자. 결과는 모두 local이다.

var vscope = 'global';
function fscope(){
    vscope = 'local';
    alert('함수안'+vscope);
}
fscope();
alert('함수밖'+vscope);

함수밖에서도 vscope의 값이 local인 이유는 무엇일까? 그것은 함수 fscope의 지역변수를 선언할 때 var를 사용하지 않았기 때문이다. var를 사용하지 않은 지역변수는 전역변수가 된다. 따라서 3행은 전역변수의 값을 local로 변경하게 된 것이다. var을 쓰는 것과 쓰지 않는 것의 차이를 이해해야 한다.

전역변수는 사용하지 않는 것이 좋다. 여러가지 이유로 그 값이 변경될 수 있기 때문이다. 함수 안에서 전역변수를 사용하고 있는데, 누군가에 의해서 전역변수의 값이 달라졌다면 어떻게 될까? 함수의 동작도 달라지게 된다. 이것은 버그의 원인이 된다. 또한 함수를 다른 에플리케이션에 이식하는데도 어려움을 초래한다. 함수의 핵심은 로직의 재활용이라는 점을 상기하자. 변수를 선언할 때는 꼭 var을 붙이는 것을 습관화해야 한다. 전역변수를 사용해야 하는 경우라면 그것을 사용하는 이유를 명확히 알고 있을 때 사용하도록 하자.

유효범위의 효용

아래 두개의 예제는 변수 i를 지역변수로 사용했을 때와 전역변수로 사용했을 때의 차이점을 보여준다. 전역변수는 각기 다른 로직에서 사용하는 같은 이름의 변수값을 변경시켜서 의도하지 않은 문제를 발생시킨다.

지역변수의 사용

function a (){
    var i = 0;
}
for(var i = 0; i < 5; i++){
	a();
	document.write(i);
}

 실행결과

01234

전역변수의 사용

본 예제는 무한반복을 발생시킨다. 
function a (){
    i = 0;
}
for(i = 0; i < 5; i++){
	a();
	document.write(i);
}

전역변수의 사용

불가피하게 전역변수를 사용해야 하는 경우는 하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리하는 방법을 사용한다.

MYAPP = {}
MYAPP.calculator = {
    'left' : null,
	'right' : null
}
MYAPP.coordinate = {
	'left' : null,
	'right' : null	
}

MYAPP.calculator.left = 10;
MYAPP.calculator.right = 20;
function sum(){
	return MYAPP.calculator.left + MYAPP.calculator.right;
}
document.write(sum());

전역변수를 사용하고 싶지 않다면 아래와 같이 익명함수를 호출함으로서 이러한 목적을 달성할 수 있다.

(function(){
    var MYAPP = {}
	MYAPP.calculator = {
		'left' : null,
		'right' : null
	}
	MYAPP.coordinate = {
		'left' : null,
		'right' : null	
	}
	MYAPP.calculator.left = 10;
	MYAPP.calculator.right = 20;
	function sum(){
		return MYAPP.calculator.left + MYAPP.calculator.right;
	}
	document.write(sum());
}())

위와 같은 방법은 자바스크립트에서 로직을 모듈화하는 일반적인 방법이다. 

유효범위의 대상 (함수)

자바스크립트는 함수에 대한 유효범위만을 제공한다. 많은 언어들이 블록(대체로 {,})에 대한 유효범위를 제공하는 것과 다른 점이다. 아래 예제의 결과는 coding everybody이다.

for(var i = 0; i < 1; i++){
    var name = 'coding everybody';
}
alert(name);

자바에서는 아래의 코드는 허용되지 않는다. name은 지역변수로 for 문 안에서 선언 되었는데 이를 for문 밖에서 호출하고 있기 때문이다.

for(int i = 0; i < 10; i++){
	String name = "egoing";
}
System.out.println(name);

자바스크립트의 지역변수는 함수에서만 유효하다.

정적 유효범위

자바스크립트는 함수가 선언된 시점에서의 유효범위를 갖는다. 이러한 유효범위의 방식을 정적 유효범위(static scoping), 혹은 렉시컬(lexical scoping)이라고 한다. 

var i = 5;

function a(){
    var i = 10;
	b();
}

function b(){
	document.write(i);
}

a();

실행 결과는 5이다.

댓글

댓글 본문
작성자
비밀번호
  1. 쌀쌀
    너무 감사합니다 ㅜㅜ
  2. 호두
    정의된 시점
  3. 답변
    for(var i =0 i < 10; i++) {
    }
    console.log(i)
    해보시면 for 문 밖에서도 작동됩니다.
    대화보기
    • 미완성
      20190108
    • 열공
      유익한 자료 감사드립니다. 정적 유효범위에 대한 부분이 궁금했는데 이번에 확실히 인지하게 되었습니다!
    • 감사합니다.
    • 스탐
      감사합니다
    • Hero_hacker
      유효범위의 대상 (함수) 에서요, for(var i = 0; i < 1; i++) 에있는 변수i도 var로 선언되었으니까 for문밖에서도 쓸수 있는건가요??
      -아래랑 똑같은 질문인데 로그인 하고 다시 올립니다 ㅎㅎ-
    • 문장훈
      유효범위의 대상 (함수) 에서요, for(var i = 0; i < 1; i++) 에있는 변수i도 var로 선언되었으니까 for문밖에서도 쓸수 있는건가요??
    • 이전 강의에 있었던 내용이지만 알려드림
      javascript에서 함수 만드는법 3가지

      1. var 함수명 = function(){
      코드작성
      };

      2. function 함수명(){
      코드작성
      };

      3. (function(){
      코드작성
      }());

      참고로 3번이 익명함수(이름이 없는 함수, 바로 호출해야하므로 ()<<이 명령을 통해 호출함)입니다.
      대화보기
      • 감사합니다!
      • ohaeyoon@gmail.com
        자세한 설명 감사드립니다.
      • pksnbd
        ES6이 나온지 3년이 다되가는 시점에서 내용을 수정햐야 한다고 생각합니다!
      • thdbsgh3443@naver.com
        전역변수의 사용에서 (function(){ ... }()) 아라고 익명 함수에 대해서 알려주셨는데... 익명 함수 말고, 이름이 있는 함수로 만들고 싶을때는 어떻게 해야 하나요????
      • 안장호
        감사합니다~! ^^
      • 듀티프리
        좋아요. 감사합니다.
      • 고잉메리호
        동적인 유효범위는 먼지 궁금하네요. 어떤 상황일때 동적 유효범위가 적용되는지
      • javacript
        자바와는 달리 유효범위만 다르면 변수명은 같아도 충돌이 안 생기네요.
        이 부분이 잠깐 헷갈렸습니다 !
      • 들꽃향기
        자바와는 달리 지역변수의 유효범위가
        함수에서만 적용되었다니.. 기본이면서도 중요한 걸 놓친 것 같습니다.
        감사합니다.
      • 김진홍
        감사합니다~~
      • 박인호
        12-12
        수강완료.
      • Jupi
        기존 답변 수정할게요.... ;;

        이미 보셨겠지만, 이것의 답변이 되는 게 다다음 수업인 '클로저'입니다..
        클로저의 처음 수업만 봐도 이해가 빡 오실거에요 ㅎ
        대화보기
        • Jupi
          갑자기 어디선가 봤던 var같은 선언방법 중에 let 과 const가 생각나네요.
          ES6에서 생긴이유가 유효범위와 상관이 있는것 같습니다.

          아마도 강의를 만드실때는 var이외의 선언방법이 없었던거 같아요.

          참고 1
          http://blog.nekoromancer.kr......st/
          참고 2
          https://hacks.mozilla.org......st/
        • 고스트프리
          복습완료.
        • 고스트프리
          var를 왜 써야되는지 알게되었네요... 결과값이 틀려지는군요. 이해하고 넘어갑니다.^^
        • mwdkim
          조금어렵네요 ㅜㅜ 60프로는 이해되지만 40프로만 헷갈리네요 ㅜㅜ ㅎ
          좋은강의 감사드립니다.
        • rarekinel
          var i = 5;

          function a(){
          var i = 10;
          (function(){
          document.write(i);
          }())
          }

          a();

          그럼 이 경우는 어떤식으로되나요 익명함수를 사용해도 결과가 똑같나요?
        • 수복
          우와... 자바를 먼저 배운 입장에서 조금 헷갈리네요~ 특히 마지막~ ㅎㅎ
          재밌습니다~ 감사합니다.
        • GoldPenguin
          완료했습니다.
        • 박동연
          굳이 붙일 필요는 없지만 붙이는 습관을 가지면 좋을 것 같습니다!(확실하진 않네요.. 저도 배우는 입장이라서요)
          대화보기
          • MyNameDic
            유효범위 3/5에 본문에 MYAPP={} 라고 나와있는데
            앞에 var를 붙여야 하지 않을까요?
          • Jeong Min Lee
            좋은 강의 감사합니다!
          • 꽃빵
            네 그렇게 보심 돼요.
            대화보기
            • 신시내티
              변수를 선언할 때는 꼭 var을 붙이는 것을 습관화해야 한다. 전역변수를 사용해야 하는 경우라면 그것을 사용하는 이유를 명확히 알고 있을 때 사용하도록 하자.
            • 신시내티
              scope 엄청 헷갈렸는데, 완전 멋진 강의네요.
            • nevertoolate
              confusing.... ^&^;;;;;;
            • 소심한사업가
              유효범위 잘봤습니다!!
            • 세븐나이츠
              점점 어려워지고잇네요 ㅠ
            • 감사합니다!!
            • 김성희
              전역변수가 왜 위험한지, 익명함수를 왜 쓰는지를 알게 됐습니다. 감사합니다.
            • anonymous
              정말 많이 배우고 있습니다. 자바스크립트 사용하면서도 제대로 알지도 못했던 게 너무 많네요..
              이해도 너무 잘되요 감사합니다.
              정말 초급수준의 코딩만 하다보니 함수가 선언된 시점에서 유효범위를 갖는다는 사실을 처음 알았어요...
              아니면 제가 공부하면서 책에서 몇번이나 공부했던 내용일수도 있는데 그땐 저 말이 무슨 의민지 잘 몰랐겠죠..
              아무튼 정말 도움이 많이 되고 이해도 너무 잘되게 설명잘해주시네요
            • sssjunn
              감사합니다.
            • 호호
              전역변수와 지역변서 첫번째 강의 들었는데 궁금하게 있는데요
              변수부분 공부할때 처음 변수만들때는 var 쓰고 변수값 바꿀때는 이미 변수를 생성했으니
              var을 안쓰고 바로 변수 = 값 써도 된다고 하셨는데

              var vscope = 'global'
              function fscope(){
              vscope = 'local';

              }
              fscope();

              여기서도 변수값을 바꾼다는 의미로 봐도 되나요??
            • Seo Yun Seok Tudoistube
              함수의 블록에서만 지역변수이고, 나머지는 정의될때 참조할 수 있는 변수를 사용한다고 보면 되겠네요. 감사합니다^_____^!!!
            • Sk Shin
              감사합니다. ^^
            • 리느
              감사합니다.
            • crable
              감사합니다.
            • 이승우
              20170516 완료
            • 고베베
              와 감사합니다 두 분. 저도 그게 궁금했거든요!!!!
              다른 존재이기에 불러올 수 없어서 호출이 안되는거군요!
              대화보기
              • 최규선
                20170428 완료
              버전 관리
              egoing
              현재 버전
              선택 버전
              graphittie 자세히 보기