Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

민규의 개발블로그

자바스크립트 스코프 본문

Javascript

자바스크립트 스코프

규몽 2020. 11. 20. 20:38

 


스코프

스코프는 어디서 어떻게 변수를 찾는가를 결정하는 규칙의 집합이다. 변수를 검색하는 이유는 변수에 값을 대입(LHS 참조)하거나 변수의 값을 얻어오기(RHS 참조) 위함이다.

 

LHS 참조는 대입 연산 과정에서 일어난다. 스코프와 관련된 대입 연산은 '=' 연산자가 사용되거나 인자를 함수의 인자로 넘겨줄 때 일어난다.

 

자바스크립트는 일반적으로 '동적' 또는 '인터프리티' 언어로 분류하나 사실은 '컴파일러 언어'다. 

전통적인 컴파일러 언어의 처리 과정에서는 프로그램을 이루는 소스 코드가 실행되기 전에 보통 3단계를 거치는데, 이를 '컴파일레이션'이라고 한다.

 

 

컴파일러 이론

 

 

토크나이징/렉싱

 

문자열을 나누어 '토큰'이라 불리는 의미 있는 조각으로 만드는 과정이다. 

ex) var a = 2;  는 var, a, =, 2, ; 로 나눌 수 있다.(빈칸은 의미가 있냐 없냐에 따라 토큰으로 남을 수 있다.)

 

토크나이징과 렉싱은 미묘하고 학술적인 차이가 있다. '토크나이저'가 상태 유지 파싱 규칙을 적용해 a가 별개의 토큰인지 다른 토큰의 일부인지를 파악한다면 렉싱이다.

 

파싱

 

토큰 배열을 프로그램의 문법 구조를 반영하여 중첩 원소를 갖는 트리 형태로 바꾸는 과정이다. 파싱의 결과로 만들어진 트리를 AST(추상 구문 트리)라 부른다.

ex) car a = 2;의 트리는 먼저 변수 선언이라 부르는 최상위 노드에서 시작하고, 최상위 노드는 a의 값을 가지는 확인자와 대입 수식이라 부르는 자식 노드를 가진다. 대입 수식 노드는 2라는 값을 가지는 숫자 리터럴을 자식 노드로 가진다.

 

코드 생성

 

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

 

자바스크립트 엔진은 이 세 가지 단계뿐 아니라 많은 부분에서 다른 프로그래밍 언어의 컴파일러보다 복잡하다.

자바스크립트 컴파일레이션을 미리 수행하지 않아서 최적화할 시간이 많지 않다.

 


엔진: 컴파일레이션의 시작부터 끝까지 전 과정과 자바스크립트 프로그램 실행을 책임진다.

 

컴파일러: 파싱과 코드 생성의 모든 잡일을 도맡아 한다.

 

스코프: 선언된 모든 확인자(변수) 검색 목록을 작성하고 유지한다. 또, 엄격한 규칙을 강제하여 현재 실행 코드에서 확인자의 적용 방식을 정한다.

 

var a = 2; 구문은 엔진에선 두 개의 서로 다른 구문으로 보는데 하나는 컴파일러가 컴파일레이션 과정에서 처리할 구문, 다른 하나는 실행 과정에서 엔진이 처리할 구문이다.

 

컴파일러는 처음으로 렉싱을 통해 구문을 토큰으로 쪼갠다. 그 후 토큰을 파싱해 트리 구조로 만든다. 코드 생성 과정에서 컴파일러가 var a를 만나면 컴파일러는 스코프에게 변수 a가 특정한 스코프 컬렉션 안에 있는지 묻고 이미 있다면 컴파일러는 선언을 무시하고 지나가고, 없다면 컴파일러는 새로운 변수 a를 스코프 컬렉션내에 선언하라고 요청한다.

 

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

 

요약하면, 별개의 두 가지 동작을 취하여 변수 대입문을 처리한다.

첫째, 컴파일러가 변수를 선언한다.(현재 스코프에 미리 변수가 선언되지 않은 경우)

둘째, 엔진이 스코프에서 변수를 찾고 변수가 있다면 값을 대입한다.

 

LHS 검색: 대입할 대상을 찾는다.(= 연산자 사용되거나 인자를 함수의 인자로 넘겨줄 때)

RHS 검색: 대입한 값을 찾는다.

 

LHS와 RHS 참조 검색은 모두 현재 실행 중인 스코프에서 시작한다. 변수를 못 찾았을 경우 한 번에 한 스코프씩 중첩 스코프의 상위 스코프로 넘어가며 확인자를 찾는다. 글로벌 스코프에 이를 때까지 계속하고 대상을 찾았든, 못 찾았든 작업을 중단한다.

 

RHS 참조가 대상을 찾지 못하면 ReferenceError를 던지고, 검색 결과를 변수를 찾았지만 그 값을 가지고 불가능한 일을 할 경우(null이나 undefined 참조 혹은 함수가 아닌 값을 함수처럼 실행)는 엔진은 TypeError를 발생시킨다.

 

LHS 참조가 대상을 찾지 못하면 자동적, 암시적으로 글로벌 스코프에 같은 이름의 새로운 변수가 생성된다.( Strict Mode ? ReferenceError 던짐 : 새로운 변수 생성)

 

ReferenceError - 스코프에서 대상을 찾았는지와 관계

TypeError - 스코프 검색은 성공했으나 결괏값을 가지고 적합하지 않거나 불가능한 시도를 한 경우

 

 

'Javascript' 카테고리의 다른 글

자바스크립트 호이스팅  (0) 2020.11.23
자바스크립트 렉시컬 스코프  (0) 2020.11.20
자바스크립트 문법  (0) 2020.11.19
자바스크립트 강제변환-2  (0) 2020.11.17
자바스크립트 강제변환-1  (0) 2020.11.16
Comments