Closure (클로저) 너 뭐니?

💡 [코어자바스크립트-정재남, 위키북스]를 참고&인용하여 블로그를 작성했습니다.
클로저는 여러 함수형 프로그래밍 언어에서 등장하는 보편적인 특성이다. 자바스크립트만의 고유한 개념이 아니라 ECMAScript 명세에서도 클로저를 따로 정의하지 않는다.
Closure의 사전적 정의

다양한 서적에서 클로저를 한 문장으로 요약📚
- 자신을 내포하는 함수의 컨텍스트에 접근할 수 있는 함수 - 더글라스 크록포트, <자바스크립트 핵심 가이드>, 한빛미디어
- 함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 것 - 에든 브라운, <러닝 자바스크립트>, 한빛미디어
- 함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 있는 함수 - 존 레식, <자바스크립트 닌자 비급>, 인사이트
- 이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 함수 - 송형주 고현준, <인사이트 자바스크립트>, 한빛미디어
- 자유변수가 있는 함수와 자유변수를 알 수 있는 환경의 결합 - 에릭 프리먼, < Head First Javascript Programming>, 한빛미디어
- 로컬 변수를 참조하고 있는 함수 내의 함수 - 야마다 요시히로, <자바스크립트 마스터북>, 제이펍
- 자신이 생성될 때의 스코프에서 알 수 있었던 변수들 중 언젠가 자신이 실행될 때 사용할 변수들만을 기억하여 유지시키는 함수 - 유인동, <함수형 자바스크립트 프로그래밍>, 인사이트
MDN슨상님의 설명
MDN에서는 클로저에 대해 다음과 같이 설명한다.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
클로저는 함수와 함수가 선언된 당시의 lexical environment의 조합이다. 즉, 클로저는 내부 함수가 외부 함수의 스코프에 접근할 수 있게 해주는 것을 의미한다. 자바스크립트에서 함수가 생성될 때마다 함수가 생성된 시점에 클로저가 함께 생성된다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.
일단 눈으로 보고 이해해보기 👀
function outer(x) {
return function inner() {
return x
}
}
const two = outer(2)
console.log(two()) // 2
outer 함수 안에는 inner함수가 있다. inner함수는 outer 함수에 인자로 들어간 x를 리턴한다.
outer 함수가 호출되면 outer의 생명주기는 끝난다. 하지만, inner 함수는 x를 참조한다.
위의 코드 예시처럼 외부 스코프를 기억하고 있는 것을 Closure(클로저) 라고 한다.
다 이해하지 못해도 괜찮은 조-금 어려운 버전 💆🏻♂️
const outer = () => {
let a = 0
const inner = () => {
console.log((a += 1))
}
inner()
}
outer() // 1

outer함수 안에서 변수 a를 선언했고, outer함수 내부에 inner함수에서 a의 값을 1 증가시킨 후 출력했다. inner함수 내부에서 a를 선언하지 않았기 때문에 environmentRecord에서 값을 찾지 못하므로 outerEnvironmentReference에 지정된 상위 컨텍스트인 outer의 LexicalEnvironment