출처
You Don't Know JS (타입과 문법, 스코프와 클로저)
스코프는 엔진이 변수 이름으로 현재 스코프 혹은 중첩 스코프 내에서 변수를 찾을 때 사용하는 규칙의 집합이다.
스코프는 두 가지 방식으로 작동한다.
자바스크립트에서는 렉시컬 스코프를 사용하여 동작한다.
일반적인 언어의 컴파일러는 첫 단계를 토크나이징/렉싱 작업으로 시작한다.
렉시컬 스코프는 렉싱 타임(Lexing time)에 정의되는 스코프
렉시컬 스코프는 개발자가 코드를 짤 때 변수와 스코프 블록을 어디서 작성하는가에 기초해서 렉서(Lexer)가 코드를 처리할 때 확정된다.
function foo(a) {
var b = a * 2;
function bar(c) {
console.log(a,b,c);
}
bar(b*3);
}
foo(2); // 2, 4, 12
위 예제 코드에는 3개의 중첩 스코프가 있다.
엔진은 스코프의 구조와 상대적 위치를 통해 어디를 검색해야 변수를 찾을 수 있는지 안다.
스코프는 목표와 일치하는 대상을 찾는 즉시 검색을 중단한다.
여러 중첩 스코프 층에 걸쳐 같은 변수 이름을 정의 할 수 있으며, 이를 섀도잉(shadowing)이라한다.
위의 규칙에 의해 변수를 찾고 사용한다.
글로벌 변수는 자동으로 웹 브라우저의 window 같은 글로벌 객체에 속한다.
따라서 글로벌 변수를 직접 렉시컬 이름으로 참조 할 수도 있지만 객체의 속성을 참조해 간접적으로 참조할 수도 있다.
a = 2; console.log(window.a); // 2
함수가 어디서 또는 어떻게 호출되는지에 상관없이 함수의 렉시컬 스코프는 함수가 선언된 위치에 따라 정의된다.
렉시컬 스코프의 검색 과정은 a, b, c와 같은 일차 확인자 검색에만 적용된다.
코드에서 foo.bar.baz의 참조를 찾는 경우