> For the complete documentation index, see [llms.txt](https://godchiken.gitbook.io/godchiken-dev-story/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://godchiken.gitbook.io/godchiken-dev-story/front/javascript-basic/untitled-3.md).

# 스코프

자바스크립트 스코프에 대하여 정리한다.

![image](https://user-images.githubusercontent.com/16012504/64956020-a3836e00-d8c4-11e9-9556-a50209cb5887.png)

* 스코프 정의
  * 범위 내에서 식별자를 찾아내기 위한 일련의 규칙을 의미한다.&#x20;
* 스코프의 종류
  * 변수가 되었든 함수가 되었든 스코프의 개념은 동일하다.
  * 전역 스코프 : 어디서나 참조가 가능한 스코프
  * 지역 스코프
    * 함수 코드 블럭이 선언됨과 동시에 만들어지는 스코프
    * 자기 자신과, 자식 함수에서만 접근이 가능하다.
    * 하지만 자기 자신은 자식함수의 지역 스코프에 접근이 불가능하다.
* 스코프의 특징
  * 그간 다른 언어에서의 블록 스코프(block scope)에 익숙하기 때문에 혼동이 오긴한다.
  * 자바스크립트의 스코프는 함수 레벨 스코프(function-level scope)를 근간을 둔다.   &#x20;
  * ES6 부터는 블록 레벨의 스코프를 활용할 수 있다고 한다. 빨리 넘어갔으면 좋겠다.
* 전역 스코프 (Global scope)
  * 전역 스코프 영역에 선언한 변수는, 전연객체 window 의 프로퍼티가 된다.
  * 딱히 전역 스코프의 시작점은 없기에 스코프에 중요성을 모르는 개발자는 이곳 저곳에 전역 변수를 남발하여 협업과 유지보수성을 저하시킨다.
* 지역 스코프 (Local scope or Function-level scope)
  * 앞서 지역 스코프에 정리해논 정보를 조금 더 세련되게 이야기해서 함수 코드 블록 내에서  &#x20;

    선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다(참조할 수 없다)는 것이다.
  * 비유를 들어 이야기를 정리하려한다.
    * 부모와 자식이 과자를 서로 들고 있다.
    * 자식은 부모의 과자를 달라고 할 수 있다.
    * 그러나 부모의 경우 자식의 과자를 달라는 경우가 없다.
    * 부모와 자식은 함수를 비유로 들었고, 과자는 선언되어 있는 변수를 의미한다. &#x20;
* 비 블록 레벨 스코프 (Non block-level scope)
  * 앞서 말한 지역 스코프의 정리는, 함수에서 선언 되었을 때를 의미한다.
  * 그렇지 않고, 함수 밖에서 선언된 경우에는 이야기가 다르다.
  * 코드를 보자

    ```javascript
      if(true){
          var a = "am alive";
      }
      console.log(a);             //am alive
    ```
  * 위와 같은 이유는 함수 밖에서 선언된 변수는 '{}'(brace)내에 있을 지라도 전역 변수와 동급으로 취급되기 때문이다.  &#x20;
* 스코프 체인
  * (이 부분은 실행 컨텍스트에서 정리하도록 한다.)
* 렉시컬 스코프(Lexical scope) 혹은 정적 스코프(Static scope)
  * 함수가 선언됨과 동시에 스코프가 고정됨을 의미한다.
  * 정적 스코프를 따르게 되면 호출된 지점에서 가장 가까운 변수를 찾는 것이 아니라, 선언된 지점에서 가장 가까운 변수를 찾게 된다.
* 암묵적인 전역 변수 implicit global)
  * 무슨 놈의 예외가 참 많은지 모르겠으나 정리를 한다.
  * 앞서 말했다시피 지역 스코프는 함수가 선언 됨과 동시에 결정된다고 했다.
  * 하지만 만약 지역 스코프 안에서 'var' 키워드를 빼먹고 선언했을때는 다르게 동작한다.
  * 코드를 보자

    ```javascript
      function foo() {
          x = 10;         // 여기를 주목하라 'var'로 선언이 안되어있다.
      }

      foo();
      console.log(x); // ?
    ```
  * 몰랐을 경우에는 왜인지 'undefined' 가 나올 것으로 예상되나 결과는 10이다.
  * 자바스크립트 엔진은 먼저 foo 함수의 스코프에서 변수 x를 검색한다.  &#x20;
  * foo 함수의 스코프에는 변수 x에 대한 변수 선언이 없으므로 검색에 실패할 것이다.
  * foo 함수의 상위 컨텍스트(위 예제의 경우 전역 스코프)에서 변수 x를 검색한다.
  * 전역 스코프에도 변수 x가 존재하지 않기 때문에 ReferenceError를 발생시킬 것 같았다.
  * 전역 변수 x를 암묵적으로 생성하고 값을 할당한다.&#x20;
  * 이와 같이 var 키워드를 생략한 변수는 암묵적으로 전역 변수가 된다.&#x20;
  * 이러한 변수를 암묵적 전역 변수(implicit global)라 한다.
  * 그러니 실행 컨택스트를 빨리 공부하자.  &#x20;
* 그래서 이러한 스코프의 대처방안은?
  * 이론적으로 이러한 사실을 배웠다.
  * 그런데 누가 일일히 이러한 스코프를 신경 써가며 코딩하는 사람은 없다고 본다.
  * 신경을 안쓸 수 있도록 구성을 하고 코딩을 하는 사람들은 존재한다.
  * 즉시 실행 함수(IIFE, Immediately-Invoked Function Expression) 를 이용하는 방법이 그것이다.
  * 위 방법을 취하는 경우, 전역 변수를 만들지 않고 사라진다.
  * [코드를 보자](https://github.com/GodChiken/StudyES5/blob/master/src/main/resources/static/scope/scope.js)
