클로저는 자바스크립트에서 가장 매력적이면서도 때로는 헷갈리기 쉬운 개념 중 하나다. 쉽게 말해, 클로저는 함수가 생성될 때 그 함수가 참조하는 외부 변수 환경까지 함께 기억하는 기능이다. 이 덕분에 함수가 실행되고 난 뒤에도 내부에서 선언된 변수에 계속 접근할 수 있다.
클로저의 개념
자바스크립트 함수는 자신이 만들어질 당시의 스코프(변수 환경)를 기억한다. 그리고 함수가 실행될 때 이 기억한 변수 환경을 사용할 수 있다.
즉, 함수 바깥에 선언된 변수들을 함수 내부에서 그대로 ‘붙들고’ 있는 것과 같다.
왜 클로저가 생기는가?
자바스크립트에서는 함수가 내부에 다른 함수를 포함할 수 있다.
내부 함수가 외부 함수의 변수에 접근할 때, 내부 함수가 외부 함수 실행이 끝난 이후에도 그 변수에 접근할 수 있어야 한다.
이때 내부 함수가 외부 함수의 변수를 계속 기억하는 구조가 클로저다.
function makeCounter() {
let count = 0; // 외부 변수
return function() {
count++; // 외부 변수에 접근해서 값 변경
console.log(count);
}
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
위의 코드는 makeCounter라는 함수가 내부 변수 count를 만들고, 그 변수를 사용하는 함수를 반환한다. 중요한 점은 이 반환된 함수가 count를 기억하고 있다는 것이다.
makeCounter()가 실행되고 나면 일반적으로 count 변수는 사라져야 한다. 하지만 클로저 덕분에 반환된 함수는 그 count 값을 계속 유지하고 변경할 수 있다.
그래서 counter()를 여러 번 호출해도 count가 0에서 시작해 1, 2, 3 이렇게 계속 증가한다.
클로저가 필요한 이유
자바스크립트에서 클로저는 단순한 ‘기능 하나’가 아니라, 함수가 데이터를 ‘숨기고 관리하는’ 강력한 도구다. 클로저가 필요한 이유는 크게 세 가지로 정리할 수 있다.
데이터 은닉과 정보 보호
자바스크립트는 원래 클래스 기반 언어처럼 ‘private’ 변수를 쉽게 만들기 어렵다. 그런데 클로저를 사용하면, 함수 내부의 변수는 외부에서 직접 접근할 수 없게 숨길 수 있다.
예를 들어, 중요한 값이나 상태를 외부에서 막 접근하지 못하게 하고 싶을 때 클로저가 없으면 전역 변수처럼 다 노출된다. 클로저가 있으면, 그 값을 안전하게 보호하면서 내부에서만 조작할 수 있다.
상태 유지와 함수형 프로그래밍
함수는 보통 실행되면 그 안의 모든 변수가 사라진다. 그런데 클로저는 ‘함수 실행 후에도 변수 값을 기억’해서 상태를 유지할 수 있다.
이 덕분에, 버튼 클릭 횟수나 숫자 증가기처럼 상태가 변하는 기능을 깔끔하게 구현할 수 있다. 외부 변수 없이도 상태를 가진 함수를 만들 수 있으니 함수형 프로그래밍에 딱 맞는 개념이다.
함수 재사용과 유연성 극대화
클로저 덕분에 함수 하나로 여러 상황에 맞게 변수를 다르게 기억하면서 작동하는 ‘맞춤형 함수’를 만들 수 있다. 예를 들어, 특정 기준으로 필터링하는 함수나, 사용자마다 다른 설정을 기억하는 함수도 클로저로 쉽게 만들 수 있다.
이런 맞춤형 함수는 코드를 더 깔끔하고 재사용성 높게 만든다.
요약하자면
- 데이터를 숨기고 보호하기 위해
- 함수가 실행된 뒤에도 상태를 유지하기 위해
- 더 유연하고 재사용 가능한 코드를 만들기 위해
클로저는 자바스크립트에서 빼놓을 수 없는 강력한 무기다.
클로저와 메모리 관리
클로저가 메모리에 미치는 영향
클로저는 함수가 선언된 렉시컬 환경(변수가 존재하는 범위)을 기억하는 기능이다.
즉, 함수가 실행된 이후에도 해당 환경의 변수들이 메모리에 남아 있다. 이는 클로저가 변수를 ‘참조’하기 때문에 발생한다.
function makeCounter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
count 변수는 makeCounter 함수가 끝났음에도 불구하고, counter 함수가 계속 참조하기 때문에 메모리에 유지된다.
메모리 누수 가능성
클로저는 유용하지만, 잘못 사용하면 **메모리 누수(memory leak)**가 발생할 수 있다.
왜냐하면, 참조가 끊어지지 않는 변수들이 계속 메모리에 남아 있기 때문이다.
예를 들어, 오래 실행되는 애플리케이션에서 클로저가 너무 많은 변수를 오래 유지하면, 가비지 컬렉터가 메모리를 회수하지 못해 점점 메모리가 늘어난다.
가비지 컬렉션과 클로저
자바스크립트 엔진은 사용되지 않는 메모리를 자동으로 정리하는 **가비지 컬렉터(GC)**를 가지고 있다.
GC는 참조되지 않는 변수를 찾아서 메모리에서 제거한다.
하지만 클로저는 자신이 참조하는 환경의 변수들을 계속 참조하기 때문에, 가비지 컬렉터가 이 변수를 ‘사용 중’으로 판단해서 메모리를 해제하지 못한다.
메모리 관리 시 주의할 점
자바스크립트 엔진은 사용되지 않는 메모리를 자동으로 정리하는 **가비지 컬렉터(GC)**를 가지고 있다.
GC는 참조되지 않는 변수를 찾아서 메모리에서 제거한다.
하지만 클로저는 자신이 참조하는 환경의 변수들을 계속 참조하기 때문에, 가비지 컬렉터가 이 변수를 ‘사용 중’으로 판단해서 메모리를 해제하지 못한다.
- 필요 없는 클로저 참조는 빨리 해제
클로저를 더 이상 사용하지 않는다면, 관련 변수를 null로 설정하거나 참조를 끊어 메모리 해제를 도와야 한다. - 큰 데이터를 클로저 안에 오래 유지하지 말 것
클로저 내부에 큰 객체나 배열 등을 보관하면 메모리 사용량이 커진다. - 반복문 안에서 클로저 주의
잘못된 클로저 사용으로 의도치 않은 메모리 사용이 늘어날 수 있으므로, 변수 스코프를 신중히 관리한다.
마무리
클로저는 매우 강력한 기능이지만, 함수 외부 변수를 계속 유지하기 때문에 메모리 사용량 증가의 원인이 될 수 있다.
따라서 클로저를 사용할 때는 꼭 필요한 변수만 참조하고, 필요 없어지면 참조를 끊어줘야 한다.
'Javascript > javascript' 카테고리의 다른 글
프론트엔드 개발자를 위한 Axios 입문 (0) | 2025.05.27 |
---|---|
fetch API란? JavaScript에서 비동기 HTTP 요청 처리 (0) | 2025.05.25 |
자바스크립트 history로 세션 히스토리 관리하기 (0) | 2023.09.26 |
자바스크립트 Math.random()으로 난수 생성하기 (0) | 2023.09.19 |
자바스크립트 parseInt() 함수를 활용한 문자열 숫자 변환하기 (0) | 2023.09.12 |