[Javascript] 클로저(Closure)의 개념

두밥비·2025년 3월 28일

article

목록 보기
5/23
post-thumbnail

🔍 클로저(Closure)란 무엇인가?

함수가 자신이 선언된 환경(스코프)을 기억하고, 그 환경 밖에서도 그 변수들에 접근할 수 있게 해주는 기능


📌 클로저의 개념

클로저(Closure)는 자바스크립트에서 매우 중요한 개념으로,
함수가 선언될 당시의 스코프(Lexical Scope)를 기억하여,
함수가 생성된 이후에도 그 스코프의 변수에 접근할 수 있게 하는 기능입니다.

다르게 표현하면,
함수가 자신이 태어난 환경을 기억하는 것
외부 함수의 실행이 끝나더라도, 내부 함수가 외부 변수에 접근 가능한 것
이라고 할 수 있습니다.

이러한 클로저는 자바스크립트의 함수가 일급 객체(First-Class Object) 라는 특성과 렉시컬 스코프(Lexical Scope) 구조에서 만들어집니다.


💡 클로저 기본 예시

function outerFunction(outerVariable) {
  return function innerFunction(innerVariable) {
    console.log(`🌏 Outer Variable: ${outerVariable}`);
    console.log(`🌟 Inner Variable: ${innerVariable}`);
  };
}

const newFunction = outerFunction('outside');
newFunction('inside');

🔨 동작 설명

  1. outerFunction('outside') 를 호출하면
    outerVariable'outside'로 설정되고,
    innerFunction을 반환합니다.

  2. newFunction('inside') 를 실행하면
    → 내부에서 outerVariable과 innerVariable을 모두 참조합니다.

  3. 중요한 점은,
    outerFunction은 이미 실행이 끝났는데도, innerFunction은 outerVariable에 접근 가능하다는 것!
    → 이게 바로 클로저입니다.


🎯 클로저는 언제 사용할까?

클로저는 다음과 같은 상황에서 매우 유용하게 사용됩니다.

1️⃣ 데이터 은닉 및 정보 보호

클로저를 활용하면 외부에서는 접근할 수 없는 비공개 변수를 만들 수 있습니다.

function createCounter() {
  let count = 0; // 외부에서는 접근 불가

  return {
    increment: () => {
      count++;
      console.log(`📈 Count: ${count}`);
    },
    decrement: () => {
      count--;
      console.log(`📉 Count: ${count}`);
    },
    getCount: () => {
      return count;
    }
  };
}

const counter = createCounter();
counter.increment(); // 📈 Count: 1
counter.increment(); // 📈 Count: 2
counter.decrement(); // 📉 Count: 1
console.log(counter.getCount()); // 1

// 외부에서 count에 직접 접근 불가능
// console.log(counter.count); → undefined

데이터 보호, 상태 유지에 효과적
✅ 외부에서는 count 변수에 직접 접근 불가, 함수 통해서만 접근 가능


2️⃣ 비동기 작업에서의 상태 유지

비동기 작업에서 특정 변수의 상태를 나중에 참조해야 할 때 클로저가 유용합니다.

function createLogger(name) {
  return function() {
    console.log(`📝 Logger: ${name}`);
  };
}

const logger = createLogger('MyApp');
setTimeout(logger, 1000); // 1초 후에 📝 Logger: MyApp 출력

1초가 지나도 name 변수를 기억하고 있습니다.
클로저가 스코프를 "기억"하기 때문


3️⃣ 반복문과 클로저 활용

자주 발생하는 실수 & 클로저의 위력

function createFunctions() {
  const functions = [];

  for (let i = 0; i < 3; i++) {
    functions.push(function() {
      console.log(`🔢 Index: ${i}`);
    });
  }

  return functions;
}

const funcs = createFunctions();
funcs[0](); // 🔢 Index: 0
funcs[1](); // 🔢 Index: 1
funcs[2](); // 🔢 Index: 2

let을 사용해 블록 스코프를 유지하면,
각 함수가 생성될 때의 i 값을 클로저로 기억해둡니다.

var로 선언하면, 모든 출력값이 3이 되는 이유도 클로저 + var의 함수 스코프 특성 때문입니다.


4️⃣ 모듈 패턴 구현

클로저는 모듈화에도 자주 사용됩니다.

const CounterModule = (function() {
  let count = 0;

  function increment() {
    count++;
    console.log(`🚀 Count: ${count}`);
  }

  function getCount() {
    return count;
  }

  return {
    increment,
    getCount
  };
})();

CounterModule.increment(); // 🚀 Count: 1
CounterModule.increment(); // 🚀 Count: 2
console.log(CounterModule.getCount()); // 2

필요한 기능만 외부에 노출
✅ 내부 데이터(count)는 은닉


🧩 추가 예시 — 파라미터 고정 (부분 적용 함수)

클로저는 부분 적용 함수(Partial Application) 를 구현할 때도 자주 사용됩니다.

function multiply(x) {
  return function (y) {
    return x * y;
  };
}

const double = multiply(2);
const triple = multiply(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

doublex = 2인 환경을 기억하는 클로저
triplex = 3인 환경을 기억
→ 각각 다른 상태를 기억하는 함수가 만들어집니다.


🚀 결론

클로저는 처음엔 조금 헷갈릴 수 있지만,
핵심은 다음 한 문장으로 요약됩니다.

"함수가 선언될 당시의 스코프를 기억하여, 생성된 이후에도 그 스코프에 접근할 수 있는 기능"

주로 데이터 보호, 상태 유지, 모듈화에 많이 사용되며, 자바스크립트의 유연하고 강력한 기능 중 하나입니다.

profile
개발새발

0개의 댓글