본문 바로가기

4일차 전역 변수 이제 그만: 클로저(Closure)로 안전한 카운터 만들기

1. 문제: "누가 내 카운터를 바꿨을까?"

자바스크립트로 클릭 횟수를 세는 기능을 만들 때, 가장 쉬운 방법은 전역 변수를 쓰는 것입니다.

 
let count = 0; // 전역 변수: 누구나 접근 가능

function click() {
  count++;
}

하지만 이 코드는 치명적인 단점이 있습니다. 어디서든 count에 접근할 수 있다는 점입니다. 다른 개발자가 실수로 count = 999라고 코드를 짜거나, 변수명이 겹치면 프로그램 전체가 꼬이게 됩니다.

"변수를 함수 안에 숨기면서도, 그 값을 계속 기억하게 할 순 없을까?" 이 고민을 해결해 주는 것이 바로 **클로저(Closure)**입니다.

2. 해결: 클로저(Closure)라는 금고

클로저는 **"이미 생명주기가 끝난 외부 함수의 변수를 참조하는 내부 함수"**를 말합니다. 쉽게 말해, 함수가 종료되어도 자신이 사용하던 변수(환경)를 '배낭'처럼 메고 다니는 것입니다.

 

[클로저를 적용한 코드]

function createCounter() {
  let count = 0; // 은닉된 변수 (외부에서 접근 불가)

  return function() {
    // count 변수는 이 내부 함수만 접근할 수 있음 (클로저)
    count += 1;
    return count;
  };
}

const myCounter = createCounter();

이제 count 변수는 createCounter 함수 내부의 '비밀 금고'에 들어갔습니다. 오직 myCounter()를 통해서만 값을 증가시킬 수 있고, 외부에서 강제로 수정하는 것은 불가능해졌습니다. 이것이 바로 **캡슐화(Encapsulation)**입니다.

3. 트러블슈팅: count++ vs ++count

구현 과정에서 예상치 못한 버그를 만났습니다. 초기값이 0인데 첫 호출 결과가 1이 아니라 0이 나온 것입니다.

[Before: 버그 발생 코드]

 
return function() {
  return count++; // 문제 발생: 값을 반환한 '후'에 1을 더함 (후위 연산)
};
  • 결과: 0 → 1 → 2

[After: 개선된 코드]

 
return function() {
  count += 1;   // 1. 값을 먼저 올리고
  return count; // 2. 반환한다 (명확한 의도)
};
  • 결과: 1 → 2 → 3

단순히 ++ 위치를 바꾸는 것보다, **"동작을 명확히 나누는 코드"**가 가독성이 좋고 실수를 줄여준다는 현업 팁을 얻었습니다.

4. 결론 (Insight)

클로저는 단순히 면접용 암기 단어가 아닙니다. **"상태(State)를 안전하게 유지관리(Maintenance)"**하기 위한 필수 기술입니다. 리액트(React)의 useState 훅도 내부적으로는 이 클로저 원리로 동작한다는 사실을 깨달았습니다.

 

컴공이지만 코딩 못함 잘하면 이름 바꿀거임
@컴공이지만 코딩 못함 잘하면 이름 바꿀거임 :: 맥북 산 김에 개발하기

맥북 산 김에 코딩 공부 열심히 해서 개발이나 해보겠습니다.

열심히 해보겠습니다

목차