소년코딩

자바스크립트 스코프에 대한 이해2

이전 포스팅(클릭) 에서 스코프는 확인자 이름으로 변수를 찾기 위한 규칙의 집합이라는 것을 알게되었다.


그러나 대개 고려해야 할 스코프는 여러 개다.


하나의 블록이나 함수는 다른 블록이나 함수 안에 중첩될 수 있으므로 스코프도 다른 스코프 안에 중첩될 수 있다.

따라서 대상 변수를 현재 스코프에서 발견하지 못하면 엔진은 다음 바깥의 스코프로 넘어가는 식으로 변수를 찾거나 글로벌 스코프라 부르는 가장 바깥 스코프에 도달할 때까지 계속한다.

 

중첩스코프

function sum(a) {
    console.log(a + b);
}
 
var b = 2;
 
sum( 2 );   // 4

b에 대한 RHS 참조는 함수 foo 안에서 처리할 수 없고, 함수를 포함하는 스코프(이 경우에는 글로벌 스코프) 에서 처리한다.

 

중첩 스코프를 탐사할 때 사용하는 간단한 규칙은 다음과 같다.

  • 엔진은 현재 스코프에서 변수를 찾기 시작하고, 찾지 못하면 한 단계씩 올라간다.
  • 최상위 글로벌 스코프에 도달하면 변수를 찾았든 못 찾았든 검색을 멈춘다

 

중첩 스코프 검색 과정을 다음과 같이 큰 빌딩으로 상상해보자.

이 빌딩은 프로그램의 중첩 스코프 규칙 집합을 나타낸다.

어디에 있든 1층은 현재 실행 중인 스코프를 뜻한다.

LHS/ RHS를 참조하려면 현재 층을 둘러보고, 찾지 못하면 엘리베이터를 타고 다음 층으로 가서 찾고, 또 다음 층으로 이동하는 식이다.

최상위 층(글로벌 스코프)에 도달했을 때 찾던 것을 발견했을 수도 있고 아닐 수도 있다.

그러나 어쨌든 검색은 거기서 중단한다.

이런것을 스코프 체이닝이라고 하는데. 스코프 체이닝에 대한 내용은 아래 링크에서 자세히 확인할 수 있다.



LHS vs RHS

LHS와 RHS를 구분하는 것이 왜 중요할까?

이 두 종류의 검색 방식은 변수가 아직 선언되지 않았을 때(검색한 모든 스코프에서 찾지 못 했을 때 서로 다르게 동작하기 때문이다.

function sum(a) {
    console.log(a + b);
    b = a;
}
 
sum( 2 );

b에 대한 첫 RHS 검색이 실패하면 다시는 b를 찾을 수 없다.

이렇게 스코프에서 찾지 못한 변수는 '선언되지 않은 변수'라 한다.

RHS 검색이 중첩 스코프 안 어디에서도 변수를 찾이 못하면 엔진이 'ReferenceError'를 발생시킨다.

여기서 중요한 점은 발생된 오류가 ReferenceError 타입이라는 것이다.


반면에, 엔진이 LHS 검색을 수행하여 변수를 찾지 못하고 꼭대기 층(글로벌 스코프)에 도착할 때 프로그램이 'Strict Mode'로 동작하고 있는 것이 아니라면, 글로벌 스코프는 엔진이 검색하는 이름을 가진 새로운 변수를 생성해서 엔진에게 넘겨준다.

즉, "없어, 없었지만 내가 널 위해 하나 만들어주지"라고 생각하면 된다.


이제, RHS 검색 결과 변수를 찾았지만 그 값을 가지고 불가능한 일을 하려고 할 경우를 보자.

예를 들어, 함수가 아닌 값을 함수처럼 실행하거나 null이나 undefined값을 참조할 때 엔진은 TypeEroor를 발생시킨다.


ReferenceError는 스코프에서 대상을 찾았는지 와 관계있지만, TypeError는 스코프 검색은 성공했으나

결과값을 가지고 적법하지 않거나 불가능한 시도를 한 경우를 의미한다.


 

마무리

  • 스코프는 어디서 어떻게 변수(확인자)를 찾는가를 결정하는 규칙의 집합이다.
  • 변수를 검색하는 이유는 변수에 값을 대입하거나(LHS 참조) 변수의 값을 얻어오기 위해서다.(RHS 참조)
  • LHS와 RHS 참조 검색은 모두 현재 실행 중인 스코프에서 시작한다. 그리고 필요하다면(대상변수를 찾지 못했을 경우)
  • 한 번에 한 스코프씩 중첩 스코프의 상위 스코프로 넘어가며 확인자를 찾는다.
  • 이 작업은 글로벌 스코프(꼭대기 층)에 이를 때까지 계속하고, 대상을 찾았든 못 찾았든 작업을 중단한다.
  • RHS 참조가 대상을 찾지 못하면 ReferenceError가 발생한다.
  • LHS 참조가 대상을 찾지 못하면 자동적, 암시적으로 글로벌 스코프에 같은 이름의 새로운 변수가 생성된다.


js2

by 소년코딩

추천은 글쓴이에게 큰 도움이 됩니다.

악플보다 무서운 무플, 댓글은 블로그 운영에 큰 힘이됩니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기