프로그램의 소스 코드를 살펴보는 건 프로그램의 정적(어휘적, lexical) 구조를 살펴보는 겁니다.
하지만 프로그램을 실제 실행하면 실행 흐름은 이곳 저곳으로 움직입니다.
함수 두 개를 쓰는 프로그램이 있다고 합시다.
function f1() {
console.log('one');
}
function f2() {
console.log('two');
}
f2();
f1();
f2();
정적으로 보면 이 프로그램은 단순히 위에서 아래로 읽어내리는 문의 연속입니다.
하지만 이 프로그램을 실행하면 실행 흐름은 읽는 순서와 다릅니다.
f1이 f2보다 먼저 정의됐지만, f2의 함수 바디가 실행된 다음 f1으로, 다시 f2로 넘어갑니다.
자바스크립트의 스코프는 정적입니다.
소스 코드만 봐도 변수가 스코프에 있는지 판단할 수 있다는 뜻입니다.
다만, 소스 코드만 봐도 즉시 스코프를 분명히 알 수 있다는 뜻은 아닙니다.
이 장에서 꼼꼼히 살피다 보면 스코프를 판단할 수 있는 몇몇 예제를 찾아볼 수 있을 겁니다.
정적 스코프는 어떤 변수가 함수 스코프 안에 있는지 함수를 정의할 때 알 수 있다는 뜻입니다.
호출할 때 알 수 있는 것은 아닙니다.
다음 예제를 보십시오.
const x = 3;
function f() {
console.log(x);
console.log(y);
}
{
// 새 스코프
const y = 5;
f();
}
변수 x는 함수 f를 정의할 때 존재하지만, y는 그렇지 않습니다.
y는 다른 스코프에 존재합니다.
다른 스코프에서 y를 선언하고 그 스코프에서 f를 호출하더라도, f를 호출하면 x는 그 바디 안의 스코프에 있지만 y는 그렇지 않습니다.
이것이 정적 스코프입니다.
함수 f는 자신이 정의될 때 접근할 수 있었던 식별자에는 여전히 접근할 수 있지만, 호출할 때 스코프에 있는 식별자에 접근할 수는 없습니다.
자바스크립트의 정적 스코프는 전역 스코프(global scope)와 블록 스코프(block scope), 함수 스코프(function scope)에 적용됩니다.