🔒 클로저란?
📖 정의
**클로저(Closure)**는 함수가 선언될 때의 렉시컬 환경(Lexical Environment)을 기억하여, 함수가 외부에서 실행되어도 그 환경에 접근할 수 있는 것을 말합니다. 간단히 말하면, 함수가 자신이 태어난 곳을 기억하는 것입니다.
🎯 비유로 이해하기
배낭 비유
클로저를 배낭에 비유하면:
엄마가 아이를 학교에 보낼 때
├─ 아이 = 함수
├─ 배낭 = 클로저
├─ 배낭 속 물건 = 외부 변수
└─ 학교 = 실행 컨텍스트
과정:
1. 엄마(외부 함수)가 아이(내부 함수)에게 배낭을 줌
2. 배낭에는 필요한 물건들(변수)이 들어있음
3. 아이는 학교(다른 곳)에 가서도
4. 배낭 속 물건을 꺼내 쓸 수 있음
5. 엄마가 없어도 배낭은 계속 있음
클로저도 마찬가지:
- 함수가 선언될 때 "배낭"을 받음
- 나중에 어디서 실행되든
- 배낭 속 변수에 접근 가능
- 외부 함수가 종료되어도 유지됨
은행 금고 비유
은행 금고 시스템
├─ 금고실 = 외부 함수
├─ 금고 = 외부 변수 (비밀 데이터)
├─ 열쇠 = 내부 함수 (접근 방법)
└─ 고객 = 외부 코드
특징:
1. 금고실이 문 닫혀도 (함수 종료)
2. 열쇠를 가진 사람은 (클로저)
3. 여전히 금고에 접근 가능 (변수 접근)
4. 다른 사람은 접근 불가 (캡슐화)
코드로:
function createVault(secret) { // 금고실
let money = secret; // 금고
return {
deposit(amount) { // 입금 열쇠
money += amount;
},
getBalance() { // 조회 열쇠
return money;
}
};
}
const myVault = createVault(1000);
myVault.deposit(500);
console.log(myVault.getBalance()); // 1500
// money에 직접 접근 불가! (보안)
사진첩 비유
사진 찍기
├─ 카메라 = 외부 함수
├─ 사진 = 클로저
├─ 배경/사람 = 변수들
└─ 현상된 사진 = 반환된 함수
과정:
1. 특정 시점에 사진 찍음 (함수 선언)
2. 그 순간의 모든 것이 사진에 담김 (변수 캡처)
3. 나중에 사진을 보면 (함수 실행)
4. 그때의 상황을 볼 수 있음 (변수 접근)
5. 실제 그 장소가 사라져도 (외부 함수 종료)
6. 사진은 영구히 남아있음 (클로저 유지)
예시:
function takePhoto(location, people) {
return function viewPhoto() {
console.log(`${location}에서 ${people}와 함께`);
};
}
const photo1 = takePhoto('제주도', '가족');
const photo2 = takePhoto('서울', '친구들');
// 나중에 어디서든
photo1(); // 제주도에서 가족과 함께
photo2(); // 서울에서 친구들과 함께
⚙️ 작동 원리
1. 렉시컬 스코프
// 스코프: 변수의 유효 범위
// 전역 스코프
let globalVar = '전역';
function outer() {
// outer 스코프
let outerVar = '외부';
function inner() {
// inner 스코프
let innerVar = '내부';
// inner는 모든 변수에 접근 가능
console.log(innerVar); // '내부'
console.log(outerVar); // '외부'
console.log(globalVar); // '전역'
}
// outer는 inner의 변수에 접근 불가
// console.log(innerVar); // ❌ 에러!
inner();
}
outer();
// 렉시컬 스코프 체인:
// inner → outer → global
// 안쪽에서 바깥쪽으로 찾아감
// 스코프는 선언 위치에 의해 결정됨 (정적)
let x = 1;
function foo() {
console.log(x);
}
function bar() {
let x = 2;
foo(); // 1 출력 (foo가 선언된 곳의 x)
}
bar();