배움/인강

한 입 크기로 잘라먹는 리액트 / 9강 - 클로저

long_tea 2025. 11. 2. 18:51

onebite

https://github.com/winterlood/onebite-react-v2/blob/main/section01/chapter13.js

 

onebite-react-v2/section01/chapter13.js at main · winterlood/onebite-react-v2

onebite-react-v2. Contribute to winterlood/onebite-react-v2 development by creating an account on GitHub.

github.com

https://github.com/winterlood/onebite-react-v2/blob/main/section01/chapter14.js

 

onebite-react-v2/section01/chapter14.js at main · winterlood/onebite-react-v2

onebite-react-v2. Contribute to winterlood/onebite-react-v2 development by creating an account on GitHub.

github.com

 

클로저 란?

함수가 선언될 당시의 스코프(환경)를 기억해서 함수 밖에서 그 변수에 접근하거나 사용할 수 있는 개념.

즉, 함수가 외부 변수를 기억하는 능력

function outer() {
 let count = 0;
 
 function inner(){
    count++;
    console.log('현재 count: ${count}');
}

return inner;
}

const counter = outer();
counter(); // 현재 count: 1
counter(); // 현재 count: 2
counter(); // 현재 count: 3

 

동작 원리

1. outer()가 실행될 때, 지역 변수 count가 생성됨

2. 내부 함수 inner()는 count 를 사용함

3. outer() 가 종료돼도, inner()가 그 변수를 참조 중이라 메모리에 남음

-> 그래서 counter()를 실행할 때마다 count가 누적됨

 

이 현상이 바로 클로저(Closure)

 

클로저를 쓰는 이유

1. 데이터 보호 (은닉화)

function createCounter() {
 let count = 0;
 return {
  increment; () => count++,
  get: () => count,
 };
}

const counter = createCounter();
counter.increment();
console.log(counter.get()); // 1

-> 외부에서는 count에 직접 접근 불가능.

-> get(), increment()로만 조작 가능.

 

2. 상태유지

  • 함수가 한 번 실행된 이후에도, 이전 상태를 계속 기억함.
  • ex) 클릭 횟수, 점수, 누적합 계산 등에 자주 사용.

주의할 점 (메모리)

  • 클로저는 참조 중인 변수를 메모리에 유지하므로 너무 많이 만들면 메모리 누수가 생길 수 있음.
let counter = outer();
counter = null; // 참조 해제 -> 가비지 컬렉션으로 정리 가능

 

- 함수는 실행될 때 자신이 선언된 스코프(환경)를 기억함

- 내부 함수가 외부 함수의 변수를 "참조"하고 있으면 -> 클로저 발생

- 주로 "상태 저장"이나 "데이터 보호"에 사용됨

- 단, 남용 시 메모리 낭비 주의

 

실무 예시

function useCounter(){
let count = 0;
return () => ++count;
}

const clickCounter = useCounter();
document.addEventListener("click", () => {
console.log("클릭 횟수:", clickCounter());
});

 

버튼 클릭할 때마다 누적 카운트가 증가하는 로직.

 

outer() 실행이 끝났는데 왜 count가 사라지지 않을까?

-> inner() 함수가 그 변수를 계속 참조 중이기 때문.

"함수가 선언될 당시의 스코프" 라는 말은?

-> 함수를 어디서 만들었는가가 중요하지, 어디서 실행하느냐는 중요하지 않음.