반응형
클로저(Closure)
- '함수와 + 그 함수가 선언된 환경(변수들)의 조합을 의미
- 함수가 생성될 당시의 외부 변수(환경)를 기억하고, 그 함수가 나중에 호출되더라고 그 변수들에 접근할 수 있는 함수
- 함수가 자신이 필요로 하는 외부 데이터를 ‘숨겨서’ 기억하고, 필요할 때 꺼내 쓸 수 있게 하는 기능
✓ Clos → "Close" (sure) → "Sure" = 확실하게 "가까이 다가가서 확실하게 담아두는 것"
✓ liken : 카메라가 어떤 장면에 클로즈업해서 중요한 디테일(변수)을 찍음
촬영이 끝나도, 그 장면은 사진(메모리) 안에 계속 저장
원본 장면(함수 본문)은 사라졌지만, 사진 속 정보(변수 상태)는 계속 꺼내볼 수 있음
* 렉시컬 환경(Lexical Environment)
- 함수가 만들어질 때 그 함수가 접근할 수 있는 변수와 함수들의 집합
- 이 집합은 함수가 선언된 위치(코드상 위치)에 따라 정해져서, “렉시컬(lexical)” 즉, “코드 텍스트 기준”이라는 뜻
- 쉽게 말해, 함수가 어디서 만들어졌느냐에 따라 변수 접근 범위가 결정된다라는 것을 의미
왜 클로저가 필요한가
- 함수가 호출될 때마다 생성된 지역변수는 보통 함수가 종료되면 그 변수는 사라짐
- 하지만 클로저를 이용하면 함수 밖에서도, 함수 종료 후에도 그 함수가 선언된 환경의 변수 값을 계속 사용할 수 있음.
즉 함수가 종료된 후에도 변수를 유지하고 싶을 때 사용하는 개념 - 따라서 상태(state)를 유지하거나, 외부 변수에 접근하는 기능을 만들 수 있음
클로저 동작 원리
- 함수가 호출될 때마다 자바스크립트 엔진은 렉시컬 환경(변수 환경)을 생성
- 이 환경에는 해당 함수가 접근할 수 있는 변수들이 저장됨
- 내부 함수는 이 환경을 기억하고, 외부 함수의 환경에 접근할 수 있음
- 그래서 외부 함수가 끝나도 내부 함수가 그 환경을 계속 참조하기 때문에 변수가 사라지지 않고 유지됨
클로저 함수(Closure Function)
- 클로저의 원리를 사용해서 만든 실제 함수
- 클로저를 생성하는 함수(내부에서 외부 변수에 접근하는 함수를 반환하거나 사용하는 함수)를 의미
- 클로저 함수는 클로저를 가지고 있는 함수 혹은 클로저를 만드는 함수를 의미하는 경우가 많음
- 클로저는 보통 외부 함수 안에 내부 함수를 선언하고, 그 내부 함수를 반환(return) 하거나 다른 곳에 전달해서 사용
- 특징
- 함수 안에 함수 존재
- 내부 함수가 외부 변수 참조
- 외부 함수가 끝나도 변수 유지
일반함수와 클로저 함수 비교
항목 | 일반함수 | 클로저 함수 |
변수 유지 | 실행 끝나면 변수 삭제 | 실행 끝나도 변수 유지 |
변수 재사용 | 매번 새로 생성 | 기존 변수 계속 사용 |
출력 예시 | "Hello", "Hello" (항상 초기 상태) | "Hello", "Hello" (같은 변수라 상태를 공유) |
응용 가능성 | 상태 저장 불가 | 상태 저장, 카운터, 정보 은닉 등 가능 |
일반함수
- normal() 실행 → msg 변수가 메모리에 생성됨
- "Hello" 출력
- 실행 끝나면 msg 변수는 메모리에서 제거됨
- 다시 실행하면 새로운 msg 변수가 만들어짐 (이전 값은 사라짐)
function normal() {
let msg = "Hello";
console.log(msg);
}
normal(); // "Hello"
normal(); // "Hello"
클로저 함수
- outer() 실행 → msg 변수가 메모리에 생성됨
- inner 함수가 반환되면서, inner는 msg 변수를 참조하고 있음
- outer 실행은 끝났지만, msg는 inner가 참조하고 있으므로 메모리에서 안 사라짐
- fn()을 실행할 때마다 같은 msg를 사용
function outer() {
let msg = "Hello";
return function inner() {
console.log(msg);
};
}
const fn = outer(); // inner 반환
fn(); // "Hello"
fn(); // "Hello"
클로저의 용도
private 변수 만들기 (정보 은닉)
- 클로저를 이용하면 외부에서 직접 접근할 수 없는 변수를 만들 수 있음
- 함수 내부 변수는 외부에서 보이지 않지만, 내부 함수가 그 변수를 기억하며 조작 가능
function createCounter() {
let count = 0; // 외부에서 직접 접근 불가
return {
increment() {
count++;
console.log(count);
},
decrement() {
count--;
console.log(count);
}
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.decrement(); // 1
console.log(counter.count); // undefined (직접 접근 불가)
/*
- count 변수는 외부에서 직접 접근할 수 없고, 오직 클로저로 연결된 함수들을 통해서만 조작 가능
- 이렇게 하면 변수 값을 안전하게 보호할 수 있음
*/
2. 상태 유지 (데이터 기억)
- 함수가 호출되고 종료되어도, 클로저가 외부 변수의 상태를 기억해서 계속 사용할 수 있음.
- 변수를 계속 기억하여 재사용 가능
- 예를 들어, 누적 합계 계산, 사용자 입력 저장, 특정 설정값 유지 등.
function outer() {
let count = 0; // outer 함수의 지역변수
function inner() {
count++;
console.log(count);
}
return inner; // inner 함수를 반환
}
const counter = outer(); // outer 실행, inner 함수가 반환됨
counter(); // 1
counter(); // 2
counter(); // 3
/*
- outer 함수가 실행될 때 count 변수가 만들어짐
- outer 내부의 inner 함수가 count 변수에 접근 가능
- outer 함수 실행이 끝났어도, inner 함수가 count 변수를 계속 기억하고 있음
- 그래서 counter()를 호출할 때마다 count 값이 1씩 증가하면서 출력됨
*/
function createAdder(x) {
return function (y) {
return x + y;
};
}
const add5 = createAdder(5); // 여기서 x = 5 로 '고정'
console.log(add5(2)); // 여기서 y = 2
/*
1.createAdder(5) 실행
- 매개변수 x에 5가 들어감
- 반환되는 함수 (y) => x + y가 클로저로 만들어짐
- 이 클로저 함수는 x를 기억하고 있음 (여기서는 5)
2. add5(2) 실행
- y에 2가 들어감
- 클로저 덕분에 x의 값(5)을 여전히 알고 있으므로 5 + 2 계산 가능
정리
- x는 이미 createAdder를 호출할 때 결정되고, 그 값이 클로저로 유지됨
- y는 반환된 함수를 실행할 때마다 새로 들어오는 값
- 띠라서, add5는 사실상 "y에 5를 더하는 함수"가 된 것
*/
3. 함수형 프로그래밍과 고차 함수 활용
- 클로저는 함수형 프로그래밍에서 고차 함수(함수를 반환하거나 인자로 받는 함수)를 구현하는 데 필수적임.
- 동적으로 함수의 동작을 만들어내거나, 인자값을 미리 기억하는 함수(부분 적용 함수, 커링 등)를 쉽게 구현 가능.
function multiplier(factor) {
return function (num) {
return num * factor;
};
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(4)); // 8
console.log(triple(4)); // 12
반응형
'JS > Javascript' 카테고리의 다른 글
[javascript] 구조 분해 할당, 배열 구조 분해 (0) | 2023.10.19 |
---|---|
[javascript] 타이머(timer) 함수 (0) | 2023.03.08 |
[함수] 중첩함수 (0) | 2023.02.25 |
[Javascript] 화살표 함수(Arrow Function) (0) | 2023.02.25 |
[Javascript] 변수 (0) | 2023.02.04 |