다시보는 JS 기본 - 클로저

김민성·2025년 4월 2일
post-thumbnail

개념

클로저는 함수가 자신이 선언된 시점의 스코프(환경)를 기억해서 나중에 호출될 때도 그 환경에 있는 변수에 접근할 수 있는 기능이다.
쉽게 말하면 함수가 "자신이 태어난 곳의 기억"을 가지고 다니는 것.

function outer() {
    let x = 10;
    return function() {
        console.log(x);
    };
}
const inner = outer();
inner(); // 10 출력

활용 방법

1. 데이터 은닉 (Data Privacy)

비공개 변수를 만들고 그 변수를 조작하는 함수만 노출할 수 있다.

function createBankAccount() {
    let balance = 0; // 외부에서 직접 접근 불가

    return {
        deposit: function(amount) {
            if (amount > 0) {
                balance += amount;
                console.log(`입금: ${amount}, 잔액: ${balance}`);
            }
        },
        withdraw: function(amount) {
            if (amount > 0 && amount <= balance) {
                balance -= amount;
                console.log(`출금: ${amount}, 잔액: ${balance}`);
            } else {
                console.log("잔액 부족 또는 잘못된 금액");
            }
        },
        getBalance: function() {
            return balance;
        }
    };
}

const myAccount = createBankAccount();
myAccount.deposit(1000);  // 입금: 1000, 잔액: 1000
myAccount.withdraw(300);  // 출금: 300, 잔액: 700
console.log(myAccount.getBalance()); // 700
console.log(myAccount.balance); // undefined (직접 접근 불가)
  • balance는 클로저 덕분에 createBankAccount 함수가 끝난 후에도 반환된 객체의 함수들이 기억하고 접근할 수 있다.

  • 외부에서는 balance를 직접 건드릴 수 없고 오직 제공된 메서드(deposit, withdraw, getBalance)로만 조작 가능하다.

2. 비동기 작업 (Asynchronous Operations)

비동기 작업에서 클로저는 함수가 실행될 때 당시의 변수를 기억하게 해줘요. 예를 들어 타이머나 이벤트 핸들러에서 유용함.

function setupDelayedMessage(name) {
    let message = `안녕, ${name}!`; // 클로저로 기억될 변수

    setTimeout(function() {
        console.log(message); // 비동기 호출 시 message를 기억
    }, 2000);
}

setupDelayedMessage("지민"); // 2초 후 "안녕, 지민!" 출력
setupDelayedMessage("태형"); // 2초 후 "안녕, 태형!" 출력

3. 모듈 패턴 (Module Pattern)

모듈 패턴은 클로저를 활용해 비공개 데이터와 공개 API를 분리할수있다.

const counterModule = (function() {
    let count = 0; // 비공개 변수

    function increment() {
        count++;
        console.log(`카운트 증가: ${count}`);
    }

    function decrement() {
        count--;
        console.log(`카운트 감소: ${count}`);
    }

    function getCount() {
        return count;
    }

    // 공개 API만 노출
    return {
        up: increment,
        down: decrement,
        value: getCount
    };
})();

counterModule.up();    // 카운트 증가: 1
counterModule.up();    // 카운트 증가: 2
counterModule.down();  // 카운트 감소: 1
console.log(counterModule.value()); // 1
console.log(counterModule.count); // undefined (비공개)
  • count는 모듈 내부에 숨겨져 있고, 외부에서는 up, down, value 메서드로만 간접적으로 접근 가능함.

  • 즉시 실행 함수(IIFE)와 클로저를 결합해서 모듈의 비공개 상태를 유지하면서 필요한 기능만 노출할수있다.

profile
다양한 경험의 개발자를 꿈꾼다

0개의 댓글