본문 바로가기

자바스크립트

클로저

클로저

  • 함수가 자신이 생성될 때의 환경(스코프)을 기억하고 그 환경의 변수 함수 등에 접근할 수 있게 해주는 특성
  • 내부 함수에서 외부 함수의 변수에 접근할 수 있다.
  • 외부 함수의 실행이 끝난 후에도 내부 함수는 외부 함수의 변수를 기억한다.
function outerFunction() {
    let outerVariable = '외부 변수';
    
    function innerFunction() {
        console.log(outerVariable);  // 외부 함수의 변수에 접근 가능
    }
    
    return innerFunction;
}

const closure = outerFunction();
closure();  // '외부 변수' 출력

 

 

내부함수를 외부로 전달하는 방법

1. 함수 반환 (return)

function outerFunction() {
    let count = 0;
    
    // 내부 함수를 직접 반환
    return function() {
        return ++count;
    };
}

const counter = outerFunction();
console.log(counter());  // 1
console.log(counter());  // 2

 

2. 콜백 함수로 전달

 

 

클로저의 활용

1. 접근 권한 제어(정보 은닉)

  • 외부에서 직접 접근할 수 없는 변수를 만들어 정보를 보호할 수 있다.
  • 외부에 제공할 정보들을 모아서 return 하고, 내부에서 사용할 정보들은 return 하지 않음으로써 접근 권한을 제어할 수 있다.
function createCounter() {
    let count = 0;  // 외부에서 직접 접근 불가능한 비공개 변수
    
    return {
        increment: function() {
            count++;
        },
        getCount: function() {
            return count;
        }
    };
}

const counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount());  // 2 출력

* count 변수에 직접 접근할 수 없지만, increment 와 getCount 를 통해 안전하게 접근할 수 있음

 

 

2. 콜백함수 내부에서 외부 데이터 사용

  • 클로저를 사용하여 콜백 함수 내에서 외부 스코프의 변수에 접근할 수 있다.
function fetchData(callback) {
  const data = { id: 1, name: "John" };
  setTimeout(() => callback(data), 1000);
}

function processUser(userId) {
  let user;
  fetchData((data) => {
    user = data;
    console.log(`User ${userId}: ${user.name}`);
  });
}

processUser(1); // 1초 후 "User 1: John" 출력

 

 

3. 부분 적용 함수

  • 기존 함수의 일부 인자를 미리 고정시켜 새로운 함수를 만드는 기법
  • 여러 인자를 한 번에 고정할 수 있으며 남은 인자를 모두 한번에 전달한다.
// 기본 함수
function add(a, b, c) {
    return a + b + c;
}

// 부분 적용 함수 구현
function partial(fn, ...fixedArgs) {
    return function(...remainingArgs) {
        return fn(...fixedArgs, ...remainingArgs);
    };
}

// 사용 예시
const addFive = partial(add, 5);
console.log(addFive(2, 3));    // 10 (5 + 2 + 3)
console.log(addFive(1, 4));    // 10 (5 + 1 + 4)

 

 

4. 커링 함수

  • 다중 인자를 받는 함수를 단일 인자를 받는 함수들의 연속으로 변환하는 기법
  • 인자를 하나씩 순차적으로 받으며 각 단계에서 하나의 인자만 처리한다.
// 일반 함수 (다중 인자)
function normalAdd(a, b, c) {
    return a + b + c;
}

// 커링 함수 (단일 인자 연속)
function curriedAdd(a) {
    return function(b) {
        return function(c) {
            return a + b + c;
        };
    };
}

// 사용 방법
console.log(normalAdd(1, 2, 3));        // 6
console.log(curriedAdd(1)(2)(3));        // 6

 

 

주의할 점

⚠️ 클로저의 변수들은 계속 메모리에 유지되므로 과도한 클로저 생성은 메모리 누수 위험이 발생할 수 있다.

→ 성능에 영향을 줄 수 있으므로 신중하게 사용하고, 더는 사용하지 않게 된 클로저에 대해서는 메모리를 차지하지 않도록 관리해줄 것!

 

어떻게? - 참조 카운트 제거하기

  • 식별자에 참조형이 아닌 기본형 데이터 null 할당
let closureFunction = (function() {
    let privateData = 'important data';
    
    function innerFunction() {
        return privateData;
    }

    return innerFunction;
})();

// 더 이상 사용하지 않을 때
closureFunction = null;
  • 꼭 필요한 경우에만 클로저 사용하기

'자바스크립트' 카테고리의 다른 글

클래스(class)  (0) 2024.12.19
프로토타입(prototype)  (0) 2024.12.18
콜백함수  (0) 2024.12.14
this  (0) 2024.12.13
실행컨텍스트(Execution Context)  (0) 2024.12.03