클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생성 시 함수가 생성될 때마다 생성됩니다.
MDN 공식문서에 나온 정의는 위와 같다.
의 조합이라고 하는데 말이 너무 어려워서 예시 코드를 보며 이해해 보았다.
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() {
// displayName() 은 내부 함수이며, 클로저다.
console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
일단 위 정의에서 나온 ‘클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공’하는 부분을 통해 displayName
이 클로저임을 알 수 있다.
why?
⇒ init
함수의 내부 함수이며, displayName
함수는 본인 외부에 있는 변수 name
을 참조하고 있기 때문이다.
그런데 저 예제의 흐름을 보면
init
함수를 실행displayName
함수를 실행console.log
로 name
을 찍기 때문에 사실 클로저라고 보기 어렵다.다음 코드를 보자.
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() {
// displayName() 은 내부 함수이며, 클로저다.
console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
}
return displayName();
}
const test = init();
test();
자, 위 예제에 대한 흐름을 보자
test
에 init
함수 호출하며 할당init
은 displayName
함수를 반환하면서 종료됨test
는 displayName
함수를 가지게 됨test
를 실행하여 displayName
함수를 실행init
함수는 종료되면서 지역변수인 name
은 존재하지 않는다displayName
는 생성될 당시의 name
을 참조하게 된다.즉 displayName
이 생성되는 시점(9번째 라인)에서 init
의 name
을 참조한다. 이것이 함수 생성 시 주변 환경(어휘적 환경)을 참조하는 것이다.