클로저(Closure)는 JavaScript의 중요한 개념 중 하나로,
함수와 그 함수가 선언된 어휘적 환경(Lexical Environment)의 조합입니다.
클로저를 이해하기 위해서는 먼저 스코프(Scope)와 스코프 체인(Scope Chain),
그리고 어휘적 환경에 대한 이해가 필요합니다.
텍스트스코프는 변수가 존재하는 범위 또는 컨텍스트를 의미하며,
어휘적 환경은 변수와 그에 상응하는 값, 그리고 상위 환경에 대한 참조를 유지하는 데이터 구조입니다.
스코프 체인은 중첩 함수의 경우, 각각의 함수 스코프가 참조를 통해 연결된 것을 의미합니다.
function outer() {
var a = 1;
function inner() {
console.log(a); // 'a'는 outer 함수의 변수다.
}
return inner;
}
var getInner = outer();
getInner(); // 1
위 예제에서 inner 함수는 outer 함수의 a라는 변수에 접근하고 있습니다.
이런 경우 inner 함수를 클로저라고 합니다.
outer 함수의 실행 컨텍스트가 종료된 이후에도 a에 접근할 수 있는 이유는,
inner 함수가 outer 함수의 환경(Lexical Environment)에 대한 참조를 가지고 있기 때문입니다.
클로저는 다음과 같은 경우에 유용하게 사용됩니다:
데이터 은닉 및 캡슐화:
클로저는 공개 API와 내부 구현 사이의 인터페이스 역할을 합니다.
JavaScript는 기본적으로 private 변수를 지원하지 않지만,
클로저를 통해 내부 변수에 대한 직접적인 접근을 막을 수 있습니다.
상태 유지:
클로저는 외부 함수의 실행이 끝난 후에도 해당 함수의 지역 변수에 접근할 수 있습니다.
이 특성을 이용하면 특정 상태를 유지하면서도 그 상태에 접근하는 API를 제공할 수 있습니다.
함수 팩토리:
클로저는 동적으로 함수를 생성하는 팩토리 역할을 할 수 있습니다.
각각의 함수는 자신만의 고유한 환경을 가지며, 이는 다양한 동작을 하는 함수를 쉽게 생성할 수 있게 합니다.
클로저를 이용하면 함수가 생성될 때의 환경을 '기억'할 수 있습니다.
이는 데이터를 은닉하거나 상태를 유지하는 데 사용될 수 있습니다.
클로저를 이용하면 함수 밖에서는 접근할 수 없는 'private' 변수를 구현할 수 있습니다.
클로저는 메모리를 소비합니다.
외부 함수의 변수를 참조하는 내부 함수(클로저)가 하나라도 존재하는 경우,
그 변수는 가비지 컬렉션의 대상이 되지 않습니다. 이로 인해 메모리 누수가 발생할 수 있습니다.
클로저의 사용이 과도하면 코드의 복잡도가 증가할 수 있습니다.
클로저의 개념은 이해하기 어렵고, 과도하게 사용하면
코드를 이해하거나 디버그하는 데 어려움을 겪을 수 있습니다.