1. 클로저란 무엇인가요? 🤔
**클로저(Closure)**란 함수와 그 함수가 선언될 당시의 **렉시컬 환경(Lexical Environment)**을 함께 기억하는 구조를 말합니다. 간단히 말해, 함수가 자신이 생성될 때의 외부 변수에 접근할 수 있는 기능입니다.
function outer() {
let outerVar = "I am from outer";
function inner() {
console.log(outerVar); // 외부 함수의 변수에 접근 가능
}
return inner;
}
const myClosure = outer();
myClosure(); // 출력: I am from outer
위 코드에서 inner 함수는 outer 함수가 종료된 이후에도 outerVar에 접근할 수 있습니다. 이것이 클로저입니다!
2. 클로저의 동작 원리 🔍
자바스크립트는 함수가 호출될 때마다 실행 컨텍스트를 생성하고, 함수 내부의 변수와 외부 변수의 참조를 저장합니다. 클로저는 이러한 참조를 유지하여 함수가 종료된 이후에도 외부 변수를 계속 사용할 수 있도록 합니다.
2.1 렉시컬 스코프와 클로저
자바스크립트는 렉시컬 스코프(Lexical Scope)를 따릅니다. 즉, 함수가 어디서 호출되었는지가 아니라, 어디서 정의되었는지에 따라 스코프가 결정됩니다.
function outer() {
let name = "JavaScript";
return function inner() {
console.log(`Hello, ${name}!`); // 렉시컬 환경의 변수 참조
};
}
const greet = outer();
greet(); // 출력: Hello, JavaScript!
greet 함수는 outer 함수가 호출될 당시의 환경을 기억하고 있습니다.
3. 클로저 활용 예시 🌟
3.1 private 변수 생성하기
클로저를 사용하면 외부에서 직접 접근할 수 없는 private 변수를 만들 수 있습니다.
function createCounter() {
let count = 0; // private 변수
return {
increment() {
count++;
console.log(count);
},
decrement() {
count--;
console.log(count);
},
};
}
const counter = createCounter();
counter.increment(); // 출력: 1
counter.increment(); // 출력: 2
counter.decrement(); // 출력: 1
count 변수는 createCounter 함수 내부에서만 접근할 수 있으며, 외부에서는 직접 수정할 수 없습니다.
3.2 한 번만 실행되는 함수 (IIFE)
즉시 실행 함수 표현식(IIFE)과 클로저를 결합하여 한 번만 실행되는 코드를 작성할 수 있습니다.
const initialize = (function () {
let isInitialized = false;
return function () {
if (!isInitialized) {
console.log("초기화 중...");
isInitialized = true;
} else {
console.log("이미 초기화되었습니다.");
}
};
})();
initialize(); // 출력: 초기화 중...
initialize(); // 출력: 이미 초기화되었습니다.
3.3 반복문에서의 클로저 활용
클로저를 사용하여 반복문에서 값의 참조를 유지할 수 있습니다.
function createFunctions() {
let functions = [];
for (let i = 0; i < 3; i++) {
functions.push(function () {
console.log(i);
});
}
return functions;
}
const funcs = createFunctions();
funcs[0](); // 출력: 0
funcs[1](); // 출력: 1
funcs[2](); // 출력: 2
위 예제에서는 let을 사용했기 때문에 각 반복에서 새로운 렉시컬 환경이 생성됩니다. 따라서 클로저가 각기 다른 값을 기억합니다.
4. 클로저 사용 시 주의할 점 ⚠️
4.1 메모리 누수
클로저는 참조를 유지하기 때문에 메모리 누수를 유발할 수 있습니다. 더 이상 필요하지 않은 클로저는 참조를 제거하여 가비지 컬렉터가 처리할 수 있도록 해야 합니다.
function outer() {
let largeData = new Array(1000000).fill("📦");
return function inner() {
console.log(largeData[0]);
};
}
const closure = outer();
// closure가 더 이상 필요 없다면 null로 설정
closure = null;
4.2 과도한 사용
클로저를 너무 많이 사용하면 코드의 복잡도가 증가할 수 있으므로, 필요할 때만 사용하는 것이 좋습니다.
마무리📜
- 클로저는 함수와 그 함수가 선언될 당시의 렉시컬 환경을 함께 기억하는 구조입니다.
- 외부 함수의 변수를 참조할 수 있으며, private 변수와 같은 다양한 패턴을 구현할 수 있습니다.
- 클로저를 사용할 때 메모리 누수와 코드 복잡성에 주의하세요.
'IT 개발 라이프 > Front-End' 카테고리의 다른 글
자바스크립트(JavaScript)의 스프레드 문법 ✨ (1) | 2024.12.18 |
---|---|
Promise와 Async의 차이점 이해하기! 🌟 (1) | 2024.12.09 |
자바스크립트 호이스팅 (Hoisting)에 대해 알아보자! 🎈 (0) | 2024.12.09 |
🔧 자바스크립트 Array Function(배열 함수) 정리 (0) | 2024.12.06 |
자바스크립트 ?. 옵셔널 체이닝(Optional Chaining) (0) | 2024.12.05 |