Javascript

클로저(Closure)란?

부지런한피로 2025. 3. 19. 05:34

클로저(Closure)함수가 자신이 선언된 환경(Lexical Scope)의 변수를 기억하고, 해당 스코프 바깥에서도 계속 접근할 수 있는 개념

클로저의 핵심 개념

  • 내부 함수(Inner Function)가 외부 함수(Outer Function)의 변수에 접근할 수 있음
  • 외부 함수가 실행을 마친 후에도 내부 함수가 외부 변수 값을 유지함
  • 데이터를 은닉(Encapsulation)하고 유지하는 데 유용

 

1. 기본적인 클로저 예제

function outer() {
  let count = 0; // 외부 함수의 변수 (내부 함수가 접근 가능)

  return function inner() { // 내부 함수 (클로저)
    count++; // 외부 함수의 변수 사용
    console.log(`현재 count 값: ${count}`);
  };
}

const counter = outer(); // outer() 실행 후, inner 함수가 반환됨

counter(); // "현재 count 값: 1"
counter(); // "현재 count 값: 2"
counter(); // "현재 count 값: 3"

📌 여기서 inner 함수는 count 변수를 기억하며 계속 사용할 수 있음.
📌 outer() 함수는 실행이 끝났지만, 내부 함수 inner()는 클로저로 인해 count 변수에 접근 가능.

 

 

2. 클로저를 활용한 데이터 은닉

클로저를 사용하면 객체의 속성을 직접 변경하지 못하도록 보호(Encapsulation)할 수 있음.

function createCounter() {
  let count = 0; // 외부에서 접근할 수 없는 private 변수

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

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

console.log(counter.count); // undefined (직접 접근 불가)

📌 count 변수는 createCounter() 내부에서 선언되었기 때문에 외부에서 직접 접근할 수 없음.
📌 대신, increment(), decrement(), getCount() 메서드를 통해서만 값을 조작할 수 있음.

 

 

3. 클로저를 활용한 이벤트 핸들러 예제

클로저는 이벤트 리스너에서 상태를 유지하는 데 유용함.

function createButtonCounter(button) {
  let count = 0;

  button.addEventListener("click", function () {
    count++;
    console.log(`버튼 클릭 횟수: ${count}`);
  });
}

const button = document.querySelector("button");
createButtonCounter(button);

📌 count 변수는 외부에서 직접 변경할 수 없고, 클릭할 때마다 클로저가 값 유지.

 

 

4. 클로저의 메모리 관리 주의점

클로저를 사용할 때 불필요한 메모리 점유를 피해야 함.
특히 큰 객체를 클로저 내부에서 계속 참조하면 가비지 컬렉션이 불가능하여 메모리 누수가 발생할 수 있음.

 

잘못된 예제 (메모리 누수 발생)

function createBigObject() {
  let bigData = new Array(1000000).fill("🚀"); // 큰 배열

  return function() {
    console.log(bigData[0]); // 클로저가 bigData를 계속 참조
  };
}

const myClosure = createBigObject();
// myClosure는 bigData를 계속 참조 -> 메모리 해제되지 않음

해결 방법 (bigData를 필요 없을 때 삭제)

function createSafeBigObject() {
  let bigData = new Array(1000000).fill("🚀");

  return function() {
    console.log(bigData[0]);
    bigData = null; // 필요 없으면 참조 해제
  };
}

const safeClosure = createSafeBigObject();
safeClosure(); // 사용 후 bigData 메모리 해제

📌 클로저 사용 후, 필요 없는 데이터를 null로 설정하여 참조를 해제하면 메모리 누수를 방지할 수 있음.

 

 

🎯 정리

클로저(Closure)란?

  • 함수가 자신이 선언된 환경의 변수를 기억하고 바깥에서도 접근할 수 있는 개념
  • 데이터 은닉(Encapsulation)상태 유지에 활용됨

클로저 활용 예시
1️⃣ 상태 유지 (counter() 예제)
2️⃣ 데이터 은닉 (객체처럼 활용 가능)
3️⃣ 이벤트 리스너에서 상태 관리
4️⃣ 비동기 처리 및 setTimeout 활용

주의할 점

  • 클로저를 잘못 사용하면 메모리 누수가 발생할 수 있음
  • 필요 없는 데이터는 참조를 해제하여 메모리 최적화 필요

📌 클로저는 JavaScript에서 강력한 기능이지만, 올바르게 사용해야 성능과 유지보수성이 좋아짐! 🚀

 

 

 

댓글수1