렉시컬(lexical)의 의미는 사전전으로는 "어휘"라는 의미이다. 자바스크립트에서는 프로그램이 구현된 "코드"와 관련돼 있음을 의미한다.
변수를 검색할 때 함수가 실행되는 환경을 근거로 판단하는것이 아니라 함수를 정의한 코드의 문맥을 근거로 판단한다는 것이다.
실행시, 각 문장이 참조하는 변수는 렉시컬 환경에서 정의한, 즉 "코드 그대로의 환경"을 기준으로 정의한 변수 스코프에서 검색한다.
다음 코드를 보자.
var x = "global";
var func = function(){
alert("x: " + x);
var x = "local";
alert("x: " + x);
};
func();
================================================
결과,
x: undefined
x: local
위 코드에는 2개의 x 변수가 있다. 하나는 전역 변수 x이고, 또 하나는 func라는 함수내에 정의된 로컬 변수 x 이다.
func 함수를 호출했을때, 첫번째 출력에서는 "x: undefined" 가 출력되고, 두번째 출력에서는 "x: local"이 출력된다.
위 코드의 파싱 단계와 실행 단계를 그림으로 표현하면 아래와 같다.
위 프로그램이 실행되는 순서는 다음과 같다.
파생 단계를 먼저 거친 후, 실행 단계를 거치게 된다.
(1) 전역 레벨의 파싱이 일어나서 파싱의 결과로 전역 변수 x와 함수변수 func가 정의 된다.
(2) 전역 레벨의 실행 단계를 거치면서 전역 변수 x에 "global"이 저장되고, 함수 func()가 호출된다.
(3) 함수 func 레벨의 파싱이 일어나고 파싱의 결과로 func 함수 내부에 있는 x가 함수 func 의 변수 스코프 객체에 정의된다.
(4) func 파싱이 끝난 후, func의 코드가 실행이 된다.
func 함수의 실행 단계에서 최초의 alert(x)에 "global"이 출력될것 같지만 "undefined"가 출력된다. 그 이유는 함수 func 가 파싱 단계에서 func 내부의 로컬 변수인 x가 파싱되면서 x: undefined로 정의가 되어 있고, 최초의alert(x)를 호출할때 로컬 변수로 정의된 func 내부의 x를 가르키기 때문이다.
즉, 쉽게 얘기해서 렉시컬한 환경을 기준으로 func 함수의 변수 스코프 객체에 정의된 x를 먼저 이용한다는것이다.
var func1 = function(){
var a = 1;
func2();
};
var func2 = function(){
return a;
};
func1();
--> 위 코드를 보면 func1() 함수를 호출하면 "a is not defined" 예외가 발생한다. 그 이유는 func2() 함수가 호출되어 a를 반환하는데 func2() 함수내부에 정의된 a 변수가 없고, 전역 변수 스코프에도 없기때문이다.
결론은,
함수가 실행되고 있는 환경에서 a를 검색하는것이 아니라 각 문장이 정의된 함수내에서 검색한다는 것이다.