쉽게 이해하는 자바스크립트 클로저(Closure)
쉽게 이해하는 자바스크립트 클로저(Closure)
자바스크립트 클로저(Closure) 는 면접에서 자주 나오고 실무에서도 정말 많이 쓰이는 개념이에요.
이번 글에서는 클로저의 정의 → 기본 예제 → 실무 활용 → 주의할 점 → 추가 학습까지 하나씩 차근차근 살펴볼게요.
📌 클로저란 무엇인가요?
클로저는 "함수와 그 함수가 선언될 당시의 렉시컬 환경(Lexical Environment)의 조합" 을 말해요.
즉, 함수가 자신이 선언된 스코프의 변수를 기억하고, 함수 실행이 끝난 뒤에도 그 변수에 접근할 수 있는 거예요.
function outerFunction() {
let outerVariable = 'I am outer!'
function innerFunction() {
console.log(outerVariable)
}
return innerFunction
}
const myClosure = outerFunction()
myClosure() // 출력: I am outer!
위 코드에서 innerFunction
은 이미 outerFunction
실행이 끝난 뒤 호출되지만, 여전히 outerVariable
에 접근할 수 있어요.
👉 이게 바로 클로저의 매력이에요!
📌 클로저의 주요 활용 사례
1. Private 변수 만들기 (데이터 숨기기)
function createCounter() {
let count = 0
return function () {
count++
console.log(count)
}
}
const increment = createCounter()
increment() // 1
increment() // 2
increment() // 3
외부에서 count
를 직접 바꿀 수 없으니 안전하게 상태를 관리할 수 있어요.
2. 상태 유지 (State Preservation)
function userSession(userId) {
let loginCount = 0
return {
login: function () {
loginCount++
console.log(`${userId}의 로그인 횟수: ${loginCount}`)
},
getLoginCount: function () {
return loginCount
},
}
}
const sessionA = userSession('userA')
sessionA.login() // userA의 로그인 횟수: 1
sessionA.login() // userA의 로그인 횟수: 2
console.log(sessionA.getLoginCount()) // 2
👉 로그인 세션, API 호출 횟수 제한 같은 기능에 잘 어울려요.
3. 함수 팩토리 (Function Factory)
function greeter(name) {
return function () {
console.log(`Hello, ${name}!`)
}
}
const greetJohn = greeter('John')
const greetJane = greeter('Jane')
greetJohn() // Hello, John!
greetJane() // Hello, Jane!
👉 버튼별 맞춤 동작 정의, 사용자별 메시지 생성 등에 자주 쓰여요.
4. 커링(Currying) 구현
function multiply(a) {
return function (b) {
return a * b
}
}
const double = multiply(2)
const triple = multiply(3)
console.log(double(5)) // 10
console.log(triple(5)) // 15
👉 할인율 계산, 단위 변환기 같은 상황에서 편리해요.
📌 클로저 사용할 때 주의할 점
-
메모리 누수 조심!
필요 없는 변수를 계속 들고 있으면 메모리를 낭비할 수 있어요. -
성능 저하 가능성
클로저는 스코프 체인을 따라가므로 과도하게 쓰면 성능이 떨어질 수 있어요. -
디버깅 어려움
값이 어디서 바뀌었는지 헷갈릴 수 있어요.
→ 크롬 개발자 도구(DevTools)에서Closure
확인 기능을 활용해 보세요.
❓ 클로저와 자주 나오는 인터뷰 질문
- 자바스크립트에서 클로저란 무엇인가요?
- 클로저를 활용해 private 변수를 어떻게 구현하나요?
- 클로저가 메모리 관리에 어떤 영향을 줄 수 있나요?
- 클로저와 스코프(Scope)의 차이는 무엇인가요?
👉 이런 질문은 면접에서 정말 자주 나와요. 미리 예제 코드를 준비해 두면 좋아요!
⚖️ 클로저와 다른 개념 비교
- 스코프(Scope): 변수가 유효한 범위를 의미해요.
- 렉시컬 환경(Lexical Environment): 코드가 작성될 당시의 변수 환경이에요.
- 클로저(Closure): 스코프와 렉시컬 환경을 함수가 기억해서 실행되는 거예요.
- this: 실행 시점의 객체를 가리키는 키워드예요. 클로저와는 별개랍니다.
⚠️ 클로저 잘못 쓰는 경우 (Anti-Pattern)
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
// 출력: 3, 3, 3
👉 var
를 쓰면 클로저 때문에 의도치 않게 같은 값이 출력돼요.
✅ 해결 방법: let
을 사용하거나 IIFE(즉시 실행 함수)로 감싸 주세요.
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
// 출력: 0, 1, 2
📌 클로저 실무 활용 예시 모음
- 웹 로그인 세션 관리
- 이벤트 핸들러 내부 상태 기억
- API 호출 제한기 (Rate Limiter)
- React/Vue 커스텀 훅에서 상태 유지
function rateLimiter(limit, interval) {
let calls = 0
let start = Date.now()
return function () {
const now = Date.now()
if (now - start > interval) {
start = now
calls = 0
}
if (calls < limit) {
calls++
console.log('API 요청 허용돼요!')
return true
} else {
console.log('요청이 제한됐어요!')
return false
}
}
}
const limitedAPI = rateLimiter(3, 5000)
limitedAPI() // API 요청 허용돼요!
limitedAPI() // API 요청 허용돼요!
limitedAPI() // API 요청 허용돼요!
limitedAPI() // 요청이 제한됐어요!
📚 추가 학습 자료
✅ 마무리
자바스크립트 클로저는 데이터 숨기기, 상태 유지, 함수 만들기, 성능 최적화 등 여러 상황에서 강력한 무기예요.
하지만 무분별하게 쓰면 오히려 메모리 낭비와 성능 저하가 생길 수 있으니 주의해야 해요.
👉 클로저를 잘 이해하고 적절하게 활용하면, 여러분의 코드가 훨씬 더 깔끔해질거에요! 🎉