Lexical Scope와 Scope Chaning

pengooseDev·2023년 1월 23일
1

Lexical Scope란?

함수를 선언하는 상위 Scope를 뜻한다.

함수의 Local Scope에 원하는 변수가 없을 때, 상위 스코프를 참조하게 된다.
여기서 말하는 상위 스코프는 함수를 선언하는 시점에서의 상위 스코프로 결정된다.

함수의 호출과는 상관이 없다.


예시 1

const scope = 'global';

const local = () => {
  const scope = 'local';
  checkScope();
};

const checkScope = () => {
  console.log(scope);
};

local(); // > global;
checkScope(); // > global;

해설

checkScope 함수는 global Scope에서 작성된 함수이다.
현재 checkScope는 scope를 콘솔로 출력해야하는 상황이다.
하지만 local Scope에 scope라는 변수는 존재하지 않는다. 따라서 local Scope에서 참조를 하지 못한 JS 엔진은 해당 Scope의 상위 Scope까지 탐색을 하게된다. 이를, Scope Chaning이라 부른다.

Scope Chaning이 발생한 시점에서, 상위 Scope를 탐색해야 한다. 이때 참조하는 상위 Scope는 함수가 호출된 위치의 상위 Scope가 아니다. 함수를 사용하기 위해 선언해두었던 그 순간에서 선언된 위치의 상위 Scope가 Scope Chaning이 발생할 때 참조하는 상위 Scope이다.

따라서, checkScope함수에서 Scope Chaning이 발생한다면 참조하게 되는 상위 Scope는 Global Scope에 속한 Global ScopeScript Scope가 된다.

만약, const scope라는 식별자를 Global Scope(또는 Script Scope)에 선언하지 아니하였다면, 참조 에러가 발생한다.

VM49:8 Uncaught ReferenceError: scope is not defined at checkScope (:8:15) at local (:4:3) at :2:1


예시 2

예시 1은 상위 Scope가 Global인 경우였다.
Scope의 선언 규칙을 읽었다면 함수의 내부에서 선언한 함수의 상위 Scope는 상위 함수의 Local Scope가 될 것이라 추론할 수 있다.
그래도 확인해보자.

const scope = 'global';

const local = () => {
    const scope = 'local';
  
    const checkScope = () => {
        console.log(scope);
    };
  
    checkScope();
};

local(); // > local;
checkScope(); // > Error;

해설

checkScope 함수는 local이라는 함수 안에서 선언되었다. 따라서 checkScope의 상위 Scopelocal함수의 localScope로 선언과 동시에 고정된다. 또한, checkScope의 Scope는 local함수의 local Scope에서만 참조가 가능하다.

따라서, local 함수를 호출하는 경우 아래의 과정을 거치게 된다.

  1. checkScope의 local Scope에서 scope식별자를 참조한다.
  2. 참조 실패.
  3. Scope Chaning이 발생하여 상위 Scope(local함수의 local Scope)를 참조한다.
  4. 참조 성공 및 출력.

한편, checkScope를 호출하는 경우 참조 에러가 발생한다.
Global Scope에서 local함수의 Local Scope는 참조할 수 없기 때문이다.


더 깊게

이쯤되면 또 하나의 의문점이 발생한다.

예시 2의 local함수의 local Scope에서 식별자 참조에 실패했다면, Global Scope까지 Scope Chaning이 발생하는가?

const scope = 'global';

const local = () => {  
  const checkScope = () => {
      console.log(scope);
  };
  checkScope();
};

local(); // > global;
checkScope(); // > Error;

해설

그렇다.

checkScope함수의 상위 Scope는 local 함수의 Local Scope이지만, local함수의 Local Scope내에서 const scope라는 식별자 참조가 불가능하다. 따라서 Global Scope까지 Scope Chaning이 발생해, Global Scope의 Script Scope에 저장되어있는 const scope = 'global을 참조해 함수를 실행한다.

물론, checkScope는 예시2와 같은 이유로 참조가 불가능해 Error가 발생한다.

0개의 댓글