[You Don't know JS] part 2-1 스코프와 클로저 - 스코프란 무엇인가 정리

728x90
반응형

스코프

특정 장소에 변수를 저장하고 나중에 그 변수를 찾는데 정의된 규칙의 집합 

 

컴파일러

  • 자바스크립트는 사실 컴파일러 언어이다. (일반적으로 동적, 인터프리터 언어로 분류됨)
  • 다른 전통적인 컴파일러 언어처럼 코드를 미리 컴파일하거나 그 결과를 분산 시스템에서 이용할 수는 없다
  • 자바스크립트 엔진이 전통적인 컴파일러 언어에서 하는 컴파일러 역할을 대부분 처리한다

전통적인 컴파일러 처리 과정

소스코드가 실행되기 전에 보통 3단계를 거치는데, 이를 컴파일레이션이라고 한다

 

1. 토크나이징/렉싱 

문자열을 나눠 토큰이라는 의미있는 조각으로 만드는 과정 

var a=2; => var / a / = / 2 / ; 

 

토크나이저가 상태 유지 파싱 규칙을 적용해 a가 별개의 토큰인지 다른 토큰 일부인지 파악한다면 그것은 렉싱이다 

(이 부분은 이렇게 쓰인게 다라서 이해를 잘 못했다.  나중에 공부할  부분)

 

2. 파싱 

  • 토큰 배열을 중첩 원소를 갖는 트리 형태로 바꾸는 과정
  • 파싱 결과로 만들어진 트리를 AST(추상 구문 트리)라 부른다

3. 코드 생성

AST를 컴퓨터에서 실행 코드로 바꾸는 과정 

 

자바스크립트 엔진

  • 다른 프로그래밍 언어 컴파일러보다 훨씬 복잡하다 (위의 세 단계보다)
  • 파싱과 코드 생성 과정에서 불필요한 요소를 삭제하는 등 실행시 성능을 최적화 
  • 자바스크립트 컴파일레이션을 미리 수행하지 않아서 최적화할 시간이 많지 않다 (JITs 등 사용해 해결)

어떤 자바스크립트 조각이라도 실행되려면 먼저 컴파일되어야 한다 

 

스코프 이해하기

 

var a=2; 가 실행될 때

 

1. 컴파일러가 var a=2; 를 만나면 스코프에게 변수 a가 특정한 스코프 컬렉션에 있는지 묻는다. 이미 있다면 컴파일러는 선언을 무시하고 없다면 새로운 변수 a를 스코프 컬렉션에 선언하라고 요청한다

 

2. 컴파일러는 a=2라는 대입문을 처리하기 위해 엔진이 실행할 수 있는 코드를 생성한다. 엔진은 먼저 스코프에게 a라는 변수가 현재 스코프 컬렉션에서 접근할 수 있는 지 확인한 후 접근 가능하면 변수 a를 사용하고 아니면 다른 스코프를 확인한다 (상위 스코프)

 

즉, 컴파일러가 변수를 선언하고 엔진이 스코프에서 변수를 찾고 있다면 대입한다 (없으면 에러가 난다)

 

컴파일러가 변수를 검색하는 법

 LHS 검색과 RHS 검색이 있다. 

 

LHS 검색: 변수가 대입연산자 왼쪽에 있을 때 ex) a=2

RHS 검색: 변수가 대입연산자 오른쪽에 있을 때 (값을 불러올 때 사용) ex) console.log(a)

 

function foo(a){
	console.log(a);
  }
  
  foo(2); 

foo(a) : foo 값을 가져오기 때문에 RHS 참조. 여기서 a=2 부분은 LHS 참조 (매개변수 부분)

console.log(a) : a의 값을 RHS 참조를 통해 가져오고 log함수 내부 인자에 LHS 검색으로 찾아 2를 대입한다

 

중첩 스코프

필요한 변수를 현재 스코프에서 찾지 못하면 상위 스코프로 이동하는데, 가장 바깥 스코프인 글로벌 스코프에 도달할 때까지 이동하며 찾는다.

 

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

foo 함수 내부에서 a값을 참조할 수 있으나 b의 값은 참조할 수 없다. 

엔진은 값을 찾자 못하면 foo 함수 스코프 외부인 글로벌 스코프에서 b의 값을 찾는다. 

 

스코프에서 변수를 찾을 수 없을 때

 

function foo(a){
console.log(a+b)
b=a;}
foo(2);
  • 위와 달리 이 코드에서 b는 어느 스코프에서도 선언되지 않았다. 이는 선언되지 않은 변수이다.
  • 엔진은 어느 스코프에서도 찾지 못하면 Reference Error를 발생시킨다.
  • strict 모드가 아닐 경우에는 글로벌 스코프는 새로운 변수를 생성해서 엔진에게 넘겨준다. (undefined)
  • 변수를 찾았지만 용도가 다르게 사용할 때 엔진은 TypeError를 발생시킨다 (ex. 함수가 아닌 것을 함수처럼 실행시킬 때)

 

728x90
반응형
TAGS.

Comments