
렉시컬 스코프란,
함수가 "어디에서 정의되었는가" 에 따라 그 함수가 접근할 수 있는 상위 스코프가 경정되는 규칙을 말하며, 정적 스코프 (Static Scope) 라고도 부른다
즉, 실행 시점이 아닌 정의된 위치에 의해 어떤 변수를 참조할 수 있을지가 결정된다
let x =1
function func1() {
let x = 10
func2()
}
function func2() {
console.log(x)
}
func1() // 1
func2() // 1
JS 는 렉시컬 스코프 (Lexical Scope) 규칙을 따르기 때문에,
func2() 가 어떤 환경에서 실행되었는지는 중요하지 않고, 어디에서 정의되었는지가 변수 참조에 영향을 준다
func2() 는 전역 스코프(Global Scope) 에서 정의되었기 때문에,
그 상위 스코프는 전역 스코프가 되며, 변수 참조 시에도 정의된 위치의 상위 스코프에서 변수를 찾게 된다
따라서 func2()에서 x를 참조할때 전역 변수인 x = 1 을 참조하게 되는것이다
Global Lexical Environment
├── x = 1
├── func1()
├── func2()
└── ↓
func2()'s Lexical Environment
└── outer: Global Lexical Environment
func2()의 렉시컬 환경은 전역 렉시컬 환경을 참조함
func1() 내부의 let x = 10은 func2()에 영향을 주지 않음
렉시컬 환경 (Lexical Environment) 이란,
코드가 실행되기 전에 생성되는 내부 객체로 해당 스코프 (블록, 함수, 스크립트 등) 에서 선언되 변수, 함수, 매개변수 등의 식별자와 그 값을 저장한다
즉, 정의된 위치를 기준으로 형성되는 스코프 환경이며, JS 엔진은 이를 바탕으로 어떤 식별자에 접근할 수 있을지 결정한다
전역 코드가 실행되기 전, JS 엔진은 전역 렉시컬 환경 객체를 생성한다
이 객체는 코드 실행 전에 미리 선언된 변수와 함수 정보를 환경 레코드 ( Environment Record) 에 저장해 두는데, 이를 통해 전역 변수 및 함수에 대한 참조가 가능해진다
JS에서 코드가 실행될 때, 엔진은 필요한 식별자 (변수, 함수 등) 를 먼저 현재 실행 중인 렉시컬 환경의 환경 레코드에서 찾는다
만약 해당 식별자가 현재 환경에 없다면, 그 렉시컬 환경이 가지고 있는 외부 렉시컬 환경에 대한 참조를 따라서 바깥쪽 스코프로 나아가며 탐색한다
이렇게 바깥 환경으로 계속 이어지는 구조를 스코프 체인 (Scope Chain) 이라고 하며, 전역 환경까지 탐색한 후에도 찾지 못하면 ReferenceError 가 발생한다