1. 클로저(Closure)란?
클로저(Closure)는 함수가 자신이 선언된 렉시컬 스코프(Lexical Scope)를 기억하고, 그 해당 스코프에 접근할 수 있는 상태를 의미합니다. 쉽게 말해서, 내부 함수가 외부 함수의 변수에 접근할 수 있는 구조를 가진다라고 생각하시면 될거 같습니다.
클로저는 자바스크립트에서 매우 중요한 개념이며, 다양한 상황에서 활용되는데 특히 데이터 은닉(Encapsulation), 콜백 함수, 모듈 패턴 등에서 자주 사용됩니다.
2. 클로저의 기본 원리
🔹 클로저의 기본 예제
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log(`Outer: ${outerVariable}, Inner: ${innerVariable}`);
};
}
const newFunction = outerFunction("Hello");
newFunction("World"); // 출력: Outer: Hello, Inner: World
🔹 실행 과정
outerFunction
이 호출되면서outerVariable
에 "Hello"가 저장됩니다.innerFunction
이 반환되지만,outerFunction
의 실행이 종료되어도outerVariable
이 사라지지 않고 유지됩니다.newFunction("World")
을 실행하면 내부 함수에서outerVariable
을 접근할 수 있습니다.
이처럼 내부 함수는 외부 함수의 변수에 접근할 수 있으며, 실행이 종료된 후에도 해당 변수는 유지됩니다. 이것이 바로 클로저의 핵심 개념입니다.
3. 클로저의 활용 사례
1️⃣ 데이터 은닉 (Encapsulation)
클로저를 이용하면 외부에서 직접 접근할 수 없는 변수를 만들 수 있는데요.
function createCounter() {
let count = 0; // 외부에서 접근할 수 없는 변수
return {
increase: function() { count++; console.log(count); },
decrease: function() { count--; console.log(count); },
getCount: function() { return count; }
};
}
const counter = createCounter();
counter.increase(); // 1
counter.increase(); // 2
console.log(counter.getCount()); // 2
✅ count
변수는 createCounter
내부에서만 유지되므로, 외부에서 직접 접근 하거나 수정할 수 없습니다.
2️⃣ 반복문과 setTimeout
문제 해결
클로저는 setTimeout
과 함께 사용할 때 유용합니다.
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
// 출력: 3, 3, 3 (모든 타이머가 같은 `i` 값을 참조)
이 문제를 해결하려면 클로저를 사용합니다.
for (var i = 0; i < 3; i++) {
(function(index) {
setTimeout(function() {
console.log(index);
}, 1000);
})(i);
}
// 출력: 0, 1, 2 (올바른 결과)
✅ 즉시 실행 함수(IIFE)를 활용하여 index
값을 클로저에 저장하면 예상 했던 결과를 출력하게 동작합니다.
3️⃣ 함수 커링(Function Currying)
클로저를 활용하면 함수를 부분적으로 적용하는 기법인 (커링, Currying)을 구현할 수 있습니다.
function multiply(a) {
return function(b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5)); // 10
console.log(double(10)); // 20
✅ multiply(2)
가 실행된 후에도 a
값이 유지되기 때문에, 새로운 인자를 받아서 연산을 수행할 수 있습니다.
4. 클로저 사용 시 주의할 점
✅ 메모리 누수 가능성
- 클로저는 참조하는 변수들을 계속 유지하기 때문에 불필요한 변수가 메모리를 차지할 수 있습니다.
- 필요하지 않은 경우 클로저 변수를
null
로 설정하여 해제하는 것이 좋습니다.
✅ 성능 저하 문제
- 너무 많은 클로저를 사용하면 메모리 사용량 증가로 인해 성능이 저하될 수 있습니다.
- 그렇기 때문에 클로저를 남용하지 않고 필요한 곳에서만 적절히 사용하는 것이 중요합니다.
5. 결론
클로저는 자바스크립트에서 스코프와 변수를 효율적으로 관리할 수 있는 아주 중요한 개념입니다. 이를 잘 활용하면 데이터 은닉, 비동기 처리, 함수 커링 등 다양한 프로그래밍 기법을 쉽게 구현할 수 있습니다.
하지만 클로저를 무분별하게 사용하면 메모리 누수와 성능 저하를 초래할 수 있으므로, 필요할 때만 적절하게 활용하는 것이 아주 중요합니다.