PUBLISHED

렉시컬 스코프 v 렉시컬 환경

작성일: 2025.02.13

렉시컬 스코프 v 렉시컬 환경

렉시컬 스코프라는 용어를 처음 접했을 때, 나는 이것을 별다른 의심 없이 ‘렉시컬 환경에 따른 스코프 체인’ 정도로 이해했다. 두 개념이 밀접하게 연결되어 있다는 인상 때문이었을 것이다. 그 결과, 모 회사의 면접에서 렉시컬 스코프를 설명해 보라는 질문을 받았을 때 스코프 체인에 대한 설명만을 늘어놓고 말았다.

면접이 끝난 뒤, 렉시컬 스코프와 스코프 체인은 다른 개념이라는 피드백을 들었다. 하지만 왜 다른지, 무엇이 다른지, 어떤 관점에서 구분해야 하는지는 명확히 설명할 수 없었다. 이후 코어 자바스크립트YDKJSY를 차례로 읽으며, 이 두 개념이 비슷해 보일 뿐 실제로는 서로 다른 레이어의 개념이라는 사실을 비로소 이해하게 되었다.

렉시컬 스코프는 변수와 함수의 유효 범위가 어디에서 선언되었는지에 의해 결정된다는 원칙을 의미한다. 이는 정적으로 결정되는 규칙이며, 코드가 작성된 위치에 의해 스코프가 고정된다. 다시 말해, 함수가 어느 코드 블록 안에서 선언되었는지가 그 함수가 접근할 수 있는 변수의 범위를 결정하며, 이 결정은 실행 시점의 호출 방식이나 실행 흐름에 의해 바뀌지 않는다.

이러한 이유로 렉시컬 스코프는 흔히 컴파일 타임에 결정된다고 설명된다. 실제로 자바스크립트 엔진은 코드를 실행하기 전에 이미 변수 접근 가능 여부를 구조적으로 확정해 두며, 이후 실행 과정에서는 이 규칙을 변경하지 않는다.

반면 렉시컬 환경은 변수와 함수가 실제로 어떤 값을 가지고 있는지를 저장하고 관리하는 실행 시점의 구조이다. 렉시컬 환경은 환경 레코드(Environment Record)를 통해 해당 스코프 내의 식별자와 그에 대응하는 값을 관리한다. 여기에는 변수 선언, 함수 선언, 매개변수, 그리고 this 바인딩과 같은 정보가 포함된다.

즉, 렉시컬 스코프가 “어디까지 접근할 수 있는가”를 정의하는 규칙이라면, 렉시컬 환경은 “그 접근 가능한 식별자들이 현재 어떤 상태를 가지고 있는가”를 관리하는 구체적인 메커니즘이다. 이 관점에서 렉시컬 환경은 렉시컬 스코프가 런타임에 실체화된 결과물이라고 볼 수 있다.

렉시컬 환경은 실행 컨텍스트가 생성될 때마다 동적으로 만들어진다. 각 실행 컨텍스트는 자신만의 렉시컬 환경을 가지며, 동시에 외부 렉시컬 환경에 대한 참조를 유지한다. 이 참조의 연결 구조가 바로 스코프 체인이다. 스코프 체인은 현재 실행 중인 코드가 어떤 렉시컬 환경들에 접근할 수 있는지를 선형적으로 연결한 구조이며, 변수 조회 시 이 체인을 따라 상위 환경으로 탐색을 진행한다. 따라서 스코프 체인은 렉시컬 스코프라는 규칙을 기반으로 하되, 실제 동작은 렉시컬 환경 간의 참조 관계를 통해 이루어진다.

이러한 맥락에서 클로저 역시 렉시컬 스코프 자체보다는 렉시컬 환경에 더 직접적으로 의존한다. 함수가 선언될 당시의 외부 렉시컬 환경에 대한 참조가 유지되기 때문에, 함수 실행이 끝난 이후에도 해당 환경의 값에 접근할 수 있는 것이다. 이는 “스코프 규칙”이 아니라 “환경이 유지되는 방식”의 문제에 가깝다.

정리하면 다음과 같다. 렉시컬 스코프는 컴파일 타임에 결정되는 변수 유효 범위에 대한 규칙이며, 렉시컬 환경은 그 규칙을 바탕으로 자바스크립트 엔진이 런타임에 변수와 값을 관리하는 실제 구조이다. 스코프 체인과 클로저는 렉시컬 스코프 위에 존재하지만, 그 동작의 중심에는 항상 렉시컬 환경이 있다.