MDN에 클로저의 정의는 ‘함수와 함수가 선언된 어휘적 환경의 조합이다’ 라고 나타나 있다.
그리고 클로저를 이해하려면 렉시컬 스코프(Lexical Scope)를 먼저 이해해야 한다고 나와있다.
따라서, 렉시컬 스코프가 무엇인지 먼저 알아보자.
스코프란 참조 대상 식별자(변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다.
간단한 예제로 설명하자면 다음과 같다.
/*
전역에 변수를 선언하면 이 변수는 어디서든지 참조할 수 있는
"전역 스코프"를 가지는 전역 변수가 된다.
*/
var global = 'global';
function foo() {
// var 키워드로 선언한 변수는 "함수 레벨 스코프"를 가진다.
var local = 'local';
console.log(global);
}
foo();
console.log(local);
// 결과
// global
// Uncaught ReferenceError: local is not defined
위 예제에서 global 이름을 가진 변수는 전역 스코프를 가지기 때문에 foo 함수 내에서도 참조할 수 있지만, local 이름을 가진 변수는 함수 레벨 스코프를 가지므로 foo 함수 외부에서 참조하려고 한다면 참조에러가 발생한다. 즉, 이와 같은 개념을 스코프라 한다.
렉시컬 스코프는 함수를 어디에 선언하였는지에 따라 상위 스코프가 결정되는 것을 말한다.
자바스크립트를 포함한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따르며, 이를 정적 스코프(Static Scope)라고 부르기도 한다.
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // 1
bar(); // 1
위와 같은 상황에서 bar 함수에서 참조하는 x 변수는 bar 함수의 상위 스코프가 무엇인지에 따라 결정된다.