Scope를 다시 복습해보자면 엔진이 현재 스코프 또는 중첩 스코프 내에서 변수를 찾을 때 사용하는 규칙으로 정의했다.
Scope는 2가지 방식으로 동작한다.
-
렉시컬 스코프(Lexical Scope)
-
동적 스코프(Dynamic Scope)
자바스크립트에서는 렉시컬 스코프를 채용했다.
Scope에서 다뤘던 것처럼 컴파일러는 첫 단계로 토크나이징 작업을 하게 된다. 토크나이징은 또 다른 말로 렉싱이라고 불리우기도 한다.
렉싱타임에서 소스코드 문자열을 분석하여 파싱의 결과로 생성된 토큰에 의미를 부여하게 되는데 이것이 렉시컬 스코프의 어원의 바탕이 된다.
쉽게 이야기하면 렉시컬 스코프 는 렉싱타임에 정의되는 스코프로 프로그래머가 코드를 짤 때 변수와 스코프 블록을 어디에 작성(선언)하는가에 따라 결정되는 것이다.
요약 -> 어떤 함수가 어디서 또는 어떻게 호출되는지에 상관없이 함수의 스코프는 함수가 선언된 위치에 따라 렉시컬 스코프가 결정된다.
렉시컬 스코프는 프로그래머가 함수를 어디에 선언했는지에 따라 결정된다. 하지만 런타임 때 렉시컬 스코프를 속일(수정)할 방법이 존재한다.
eval 함수와 with함수가 대표적인 예이다.
이들은 선언되는 시점이 아닌 호출되는 시점에 마치 처음부터 선언되어 있었던 것처럼 눈속임을 할 수 있다.
물론 이러한 방법으로 더 복잡한 기능과 유연함을 얻을 수도 있지만 이러한 방법은 사용하지 않는 것이 좋다.
자바스크립트 엔진은 컴파일레이션 단계에서 상당수의 최적화 작업을 진행한다. 이 작업을 통해 비로소 모든 변수와 함수가 어디에 있는지 파악하고 실행과정에 있어 더 빠른속도를 가능하게 해준다.
하지만 eval이나 with함수를 사용하게 될 시, 엔진은 미리 확인해둔 식별자 위치가 틀릴 수도 있다고 가정해야 한다.
컴파일레이션 단계에서 미리 최적화한 렉시컬 스코프가 eval이나 with함수로 인해 렉시컬 스코프가 수정되거나 생성되어야 할 수도 있기 때문이다.
eval과 with를 사용했다는 사실 하나만으로도 최적화가 무의미해지기 때문에 이러한 방법은 피해야 한다.