클로저는 함수와 그 함수가 선언된 렉시컬 환경(lexical scope)에 대한 참조로 구성된 특별한 객체입니다. 다르게 말하면, 함수가 선언된 환경 밖에서 호출되더라도 그 함수는 자신이 선언됐던 환경을 "기억"하게 됩니다.
렉시컬 스코핑 (Lexical Scoping):
JavaScript는 렉시컬 스코핑(또는 정적 스코핑)을 사용합니다. 이는 함수의 스코프가 함수가 어디에서 호출되는지가 아닌, 어디에서 선언되었는지에 의해 결정된다는 것을 의미합니다.
내부 함수와 외부 함수:
함수 내부에 정의된 함수(내부 함수)는 외부 함수의 변수에 접근할 수 있습니다. 내부 함수가 외부 함수의 변수를 참조하고 있을 때, 그 내부 함수를 클로저라고 합니다.
function outerFunction() {
let outerVariable = "I'm an outer variable";
function innerFunction() {
console.log(outerVariable); // innerFunction은 outerVariable에 접근할 수 있습니다.
}
return innerFunction;
}
const myClosure = outerFunction();
myClosure(); // "I'm an outer variable"를 출력합니다.
위의 예제에서 innerFunction은 outerVariable에 접근하는 클로저입니다. outerFunction이 실행된 후에도 myClosure를 호출할 때, innerFunction은 여전히 outerVariable에 접근할 수 있습니다.
데이터 은닉 및 캡슐화:
클로저를 사용하면 특정 데이터나 함수를 외부에서 직접 접근할 수 없게 숨길 수 있습니다. 이를 통해 모듈 패턴 등에서 private한 상태나 메서드를 생성하는데 활용됩니다.
동적 함수 생성:
함수를 동적으로 생성하고, 특정 상태를 저장하는 함수를 반환할 수 있습니다.
콜백 및 이벤트 리스너:
비동기 코드나 이벤트 리스너에서 특정 상태나 데이터를 참조해야 할 때 클로저를 활용할 수 있습니다.
타이머와 딜레이:
setTimeout 또는 setInterval에서 클로저를 사용하여 외부 스코프의 변수를 참조하게 만들 수 있습니다.
클로저는 JavaScript의 중요한 특성 중 하나로, 함수형 프로그래밍에서도 자주 사용되는 개념입니다. 클로저를 이해하고 활용하면 JavaScript에서 많은 문제를 효과적으로 해결할 수 있습니다.