JavaScript를 사용하다 보면 "클로저(Closure)"라는 개념을 접하게 됩니다. 클로저는 자바스크립트의 강력한 기능 중 하나로, 함수와 함수가 선언된 렉시컬 환경의 조합을 의미합니다. 이번 글에서는 클로저의 원리와 활용 방법에 대해 자세히 알아보겠습니다.
클로저란 무엇인가?
클로저는 함수가 생성될 때 함께 생성된 환경을 기억하는 기능입니다. 이 환경에는 함수가 생성될 당시의 변수들이 포함됩니다. 쉽게 말해, 클로저는 함수가 선언된 스코프 외부에서도 해당 스코프의 변수를 기억하고 접근할 수 있게 합니다.
클로저의 기본 예제
아래는 클로저의 기본적인 예제입니다:
function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
const myFunction = outerFunction();
myFunction(); // I am outside!
위 코드에서 innerFunction은 outerFunction의 내부 변수인 outerVariable에 접근할 수 있습니다. 이는 innerFunction이 outerFunction의 렉시컬 환경을 기억하기 때문입니다.
클로저의 활용 방법
클로저는 다양한 상황에서 유용하게 사용할 수 있습니다. 몇 가지 활용 예제를 살펴보겠습니다.
1. 데이터 은닉화
클로저를 사용하면 함수 내부의 데이터를 외부에서 직접 접근할 수 없도록 은닉화할 수 있습니다.
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
},
getCount: function() {
return count;
}
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount()); // 2
console.log(counter.decrement()); // 1
위 예제에서 count 변수는 createCounter 함수의 외부에서는 직접 접근할 수 없고, 오직 반환된 객체의 메서드를 통해서만 접근할 수 있습니다.
2. 함수의 부분 적용
클로저를 이용하여 함수의 일부 인수를 고정하고 나머지 인수만 나중에 전달할 수 있습니다.
function multiply(a) {
return function(b) {
return a * b;
};
}
const multiplyByTwo = multiply(2);
console.log(multiplyByTwo(5)); // 10
console.log(multiplyByTwo(10)); // 20
multiply 함수는 a 값을 고정한 새로운 함수를 반환하며, 반환된 함수는 나머지 인수 b를 받아 결과를 계산합니다.
3. 이벤트 핸들러에서 클로저 사용
이벤트 핸들러에서 클로저를 사용하면 특정 상태를 유지하면서 콜백 함수에 접근할 수 있습니다.
function setupHandlers() {
let message = 'Button clicked!';
document.getElementById('myButton').addEventListener('click', function() {
alert(message);
});
}
setupHandlers();
setupHandlers 함수 내부의 message 변수는 클릭 이벤트 핸들러 내부에서 참조할 수 있으며, 이는 클로저 덕분입니다.
결론
클로저는 자바스크립트에서 매우 유용한 개념으로, 이를 활용하면 데이터 은닉화, 함수의 부분 적용, 이벤트 핸들러 등 다양한 상황에서 코드의 가독성과 유지보수성을 높일 수 있습니다. 클로저의 작동 원리와 다양한 활용 방법을 이해하고 나면, 더욱 효율적인 자바스크립트 코드를 작성할 수 있을 것입니다.