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. 박인호
    12-12
    수강완료.
  2. 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 완료
          • 신입1
            감사합니다
          • richblue
            1/5 전역변수 와 지역변수
            JS는 함수형언어
            함수는 모듈화 근간, 코드 재사용 , 정보 구성, 정보 은닉 , 행위 지정
            함수안 변수는 var 키워드를 사용해서 지역변수로 선언하자.
            똑같은 이름의 변수를 다른 의미로 사용할 수 있다.
          • 전성욱
            자바스크립트 구조 특성상 함수를 실행하기전 변수의 선언부분만 먼저 읽고 나머지 코드를 읽는 방식을 가지고 있습니다

            alert(a)
            var a = 1;

            이런 코드나 함수가 있으면

            var a
            alert(a)
            a = 1
            컴퓨터는 다음과 같이 읽기때문에 변수 네이밍 오류를 출력하지 않고 변수를 정의하지 않은 var의 값 undefined 를 가져오게 됩니다
            대화보기
            • 전성욱
              자바스크립트 변수는 var 생성자의 유무에 따라 같은 이름의 변수라도 사용할 수 있는 범위가 달라진다
              이것을 자바스크립트의 유효 범위가 다르다고 하는데 유효범위에 따른 변수의 종류에 대한 구분은 지역변수와 전역변수로 나눠진다
              함수 밖에서 선언한 var로 변수는 전역변수가 되며, 함수블럭 내에서 var로 선언한 변수는 지역변수가 된다.
              지역변수는 같은이름의 지역변수가 존재해도 다른 객체로 취급되어 변수명의 재사용성이 훨씬 높아진다
              지역젼수는 수명이 짧아 선언된 위상의 코드블럭이 종료되면 자동으로 사라진다
              전역변수는 보안과 가독성을 높이기 위해 보통 사용하지 않는다
              전역변수를 사용하고 싶을때 익명함수를 이용해 전역변수를 모아놓은 하나의 객체로 선언한다. 이것은 이전 강의의 모듈화에 이어지는 내용이다
              자바스크립트는 함수가 선언된 시점에서 유효범위를 가진다. 블록안에서 함수를 호출해도 그 블록의 지역변수를 가져오지 않는다
            • function a (){
              var i = 0;
              }
              에 있는 변수 i와
              for(var i = 0; i < 5; i++)에 있는 변수 i는 변수명만 같은뿐 다른 존재라고 보면 될거같아요.
              대화보기
              • 밍구르르밍
                아 var i =0;가 지역변수라서 다른곳에서는 쓸수없으니 a();를 호출한구문은 사실상 아무것도 호출하지 못하셔 그냥

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

                이 구문만 남게되어 01234가 나오는 것 일까요? 자문자답했네요..
                대화보기
                • 밍구르르밍
                  function a (){
                  var i = 0;
                  }
                  for(var i = 0; i < 5; i++){
                  a();
                  document.write(i);
                  }

                  이것도 var i =0; 으로 계속 초기화 시켜주는거 아닌가요? 지역변수여도..
                • @박

                  i가 1씩 증가하고 5보다 작을때까지 반복인데
                  a()가 계속 i를 0으로 초기화시키니

                  무한반복이 이뤄지는거죠!
                • function a (){
                  i = 0;
                  }
                  for(i = 0; i < 5; i++){
                  a();
                  document.write(i);
                  }

                  이게 무한 반복을 발생하는 이유는 뭘까요? 이해가 잘 안 돼서...
                • 임지호
                  전역변수/지역변수 : 함수 바깥에서 선언된 변수(전역적으로 영향을 미침)/함수 내에서 선언된 변수(함수 내에서만
                  영향을 미침)
                  - 전역변수는 거의 쓰이지 않음(프로그램이 커질수록 변수의 이름이 서로 헷갈릴 수 있기 때문. 이런 개념도 그러
                  한 문제때문에 고안된 것)
                  - 함수 밖에서 var를 쓰면 전역변수, 함수 안에서 var를 쓰면 지역변수
                  - 전역변수를 딱 하나만 쓰려면 전역변수 하나를 객체로 만들고 그 소속 아래 나머지 변수를 선언한다.
                  - 전역변수를 쓰지 않으려면 만든 로직을 익명함수화한다(모듈화의 기초)
                  - 자바스크립트의 지역변수는 {}가 아니라 함수!에서만 유효하다.
                  - 자바스크립트는 정적 유효범위를 채택한다(함수 호출시점이 아니라 선언 시점을 기준으로 한다)
                • 히스토
                  마지막 수업방식이 재밌네요. 문제 내주고 알아맞추기 ㅋㅋ
                • 서비
                  잘보고 갑니다...
                • 정요한
                  퍼갑니다 . ^^
                • 김명수
                  정적 유효범위! 잘 들었습니다. 감사합니다.
                • 날고기는람쥐
                  var i = 5;
                  function a(){
                  var i = i;
                  document.write(i)
                  b();
                  }

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

                  전역변수로 지정된 i가 5라는 값을 가지고 있으면서 함수 a 에선 자기 자신 i를 지역변수로 가져버리게 되는데
                  거기서 undefiend가 나오게됩니다.

                  그리고 함수 b에서 i를 호출했기에 5도 출력이 됩니다.

                  즉 두번 출력이 되어버리는것이죠
                  실제로 함수 b에서 document.write(i); 를 document write(' a ' + i ) 바꾼다면 결과는 undefined a 5 가 됩니다.

                  제 생각이 틀린것이라면 수정 답변을 달아주세요. 저두 정확한 답을 알고 싶네요.
                  대화보기
                  • 완료!
                    완료! 감사합니다.
                  • hyuna
                    감사합니다. 정리가 잘 됐습니다.
                  • 취준생1
                    오 사용될 때 정의될 때 이렇게 생각하니까 쉽군요...
                  • yihsang
                    감사합니다.
                  • kmax95@naver.com
                    ㅋㅋㅋㅋ
                    대화보기
                    버전 관리
                    egoing
                    현재 버전
                    선택 버전
                    graphittie 자세히 보기