스코프를 알아야하는 이유

(내가 보기 위한 정리)

  • 스코프 안과 스코프 밖의 변수 이름이 같아도 스코프 안의 변수가 수정되거나 재할당 되는 일을 막을 수 있다.
  • 전역 스코프의 문제점을 보완해 줄 수 있다.
  • 스코프를 이해하고 있으면 변수의 라이프 사이클을 알 수 있다.

정의

  • Scope는 모든 프로그래밍 언어에서 기본적으로 가지고 있는 개념이다.
  • 유효 범위 즉, 전역과 지역을 나누는 단위 라고 할 수 있다.
  • 변수와 매개변수의 접근성과 생존기간을 결정한다.

Global Scope

  • 전역 스코프로 모든 프로젝트의 상위 스코프가 된다.
  • 프로젝트 어디서든 글로벌 스코프에 접근이 가능하다.
  • 글로벌 스코프에 변수를 선언하게 될 경우 해당 변수는 전역 변수가 된다. 또한 전역 변수는 글로벌 스코프를 갖는다고 말할 수 있다.

Local Scope

  • 함수, 블록, 렉시컬 스코프의 { }(블록) 안을 로컬 스코프라고 한다.
  • 로컬 스코프 안에서 선언된 변수는 지역 변수가 되며, 해당 스코프 안에서만 참조가 가능하다. (var키워드로 선언한 변수는 함수 안에서만 로컬 스코프를 갖는다.)
  • 해당 로컬 스코프가 아닌 글로벌 스코프나 다른 로컬 스코프에서는 참조 시 에러가 발생한다.
  • 변수의 오염이나 의도하지 않은 재할당을 방지하기 위해서는 로컬 스코프를 활용하여 변수의 생애주기를 짧게 잡아주는 것이 좋다.

함수 레벨 스코프(function-level scope)

  • var 키워드의 스코프는 기본적으로 함수 레벨 스코프(function-level scope)이다.
    • 함수 코드 { }(블록) 내에서 선언된 변수는 함수 코드블록 내에서만 유효하고 함수 외부에서는 유효하지 않다.
    • if문의 { }(블록)이나 for문의 { }(블록)안에서의 var 키워드는 로컬 변수가 아닌 전역 변수로 읽힌다.
    • ECMAScript6에 도입된 let, const키워드를 사용하면 블록 레벨 스코프로 적용할 수 있다.
  • var 키워드의 생략
    • var 키워드를 생략하고 변수를 선언할 경우 전역 변수로 선언된다
      function scopeExam() {
        scope = 20;
        console.log('scope : ' + scope);
      }
          
      function scopeExam2() {
        console.log('scope : ' + scope);
      }
          
      scopeExam()   // 20
      scopeExam2()  // 20
      
    • var 키워드를 사용하면 생기는 다양한 문제점과 한계가 있다. 그부분에 대해서는 전역변수의 문제점과 전역변수 피하기에 정리해두었다.

렉시컬 스코프(Lexical scope) 또는 정적 스코프

  • 함수를 어디서 호출했는지 보다 어디서 선언했는지에 따라 상위 스코프가 결정되는 것을 말한다.
  • 자바스크립트는 렉시컬 스코프를 따르기때문에 함수를 호출한 시점이 아닌 함수를 선언한 시점에서 상위 스코프를 결정하게 된다.
  • 이러한 특징으로 자바스크립트의 클로저를 생각하면 이해하기 쉬울 것 같다.

    var x = 1;
      
    function foo() {
      var x = 10;
      bar();        // 
    }
      
    function bar() {
      console.log(x);
    }
      
    foo();  // 1
    bar();  // 1
    
    • 여기서 boo 함수는 foo 함수 안에서 호출되었지만 선언 자체는 글로벌 스코프 안에서 선언되었기 때문에 bar의 상위 스코프는 글로벌이 된다.

블록 레벨 스코프(Block Scope)

  • { }(블록)안의 스코프를 말하며, C언어가 대표적인 블록 레벨 스코프 언어이다.
  • 자바스크립트의 var 키워드와 달리 블록 레벨 스코프를 따르는 언어는 if문의 {}(블록)안에서 선언한 변수는 if문 밖에서는 참조할 수 없게된다.
  • ECMAScript6에 도입된 let, const키워드를 사용하면 자바스크립트도 블록 레벨 스코프로 적용할 수 있다.