JavaScript의 Closure 란?

JavaScript의 Closure 란 무엇인지 알아보고 사용 방법에 대해서 알아보자.


JavaScript의 Closure 란?

Closure 이란 무엇인가?

Closure(클로저)는 JavaScript에서 매우 중요한 개념 중 하나다. Closure는 “함수가 선언될 당시의 렉시컬 환경(Lexical Environment)을 기억하고, 그 환경에 접근할 수 있는 함수”를 말한다.

다시 말해서, Closure는 내부 함수가 외부 함수의 변수에 접근할 수 있도록 만들어 준다. 이러한 특성 덕분에 함수 외부에서는 접근할 수 없는 데이터를 은닉하거나, 데이터를 유지하는 데 사용된다.

Closure 의 특징

  1. 함수 내부에서 정의된 함수는 자신이 정의된 환경(scope)의 변수에 접근할 수 있다.
  2. 외부 함수의 실행이 종료된 후에도 내부 함수는 외부 함수의 변수에 접근할 수 있다.
  3. 데이터를 은닉하고 캡슐화하는 데 유용하다.

Closure의 구조

function outerFunction(outerVariable) {
  return function innerFunction(innerVariable) {
    console.log(`Outer Variable: ${outerVariable}`);
    console.log(`Inner Variable: ${innerVariable}`);
  };
}
 
const newFunction = outerFunction('outside');
newFunction('inside');
// 출력:
// Outer Variable: outside
// Inner Variable: inside

innerFunction은 outerFunction이 종료된 후에도 outerVariable에 접근할 수 있다. 이것이 Closure의 핵심이다.

Closure의 활용

  1. 데이터 은닉 및 캡슐화

Closure를 사용하면 외부에서 직접 접근할 수 없는 데이터를 만들 수 있다. 이를 통해 데이터 보호와 은닉을 구현할 수 있다.

function createCounter() {
  let count = 0; // 은닉된 변수
  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
counter.decrement(); // Count: 1
console.log(counter.getCount()); // 1
  1. 한번만 실행되는 초기화 함수

Closure를 사용하여 함수가 한 번만 실행되도록 설정할 수 있다.

function initialize() {
  let isInitialized = false;
 
  return function () {
    if (!isInitialized) {
      console.log('초기화 완료!');
      isInitialized = true;
    } else {
      console.log('이미 초기화되었습니다.');
    }
  };
}
 
const init = initialize();
init(); // 초기화 완료!
init(); // 이미 초기화되었습니다.
  1. 비동기 작업에서 데이터 유지하는

비동기 작업에서 Closure를 사용하면 데이터가 유지된다.

function fetchData(url) {
  setTimeout(function () {
    console.log(`Fetching data from ${url}`);
  }, 1000);
}
 
fetchData('https://example.com');

위 예제는 Closure가 데이터를 유지하며 실행된다. fetchData의 실행이 끝났음에도 url 변수를 setTimeout이 참조할 수 있다.

Closure 사용 시 주의점

  1. 메모리 누수 Closure는 참조를 유지하기 때문에, 불필요하게 Closure를 많이 사용하면 메모리 누수가 발생할 수 있다.

  2. 디버깅 어려움 Closure로 인해 코드의 실행 흐름을 추적하기 어렵게 되는 경우가 있다.

정리

Closure는 데이터 은닉, 상태 유지, 비동기 작업 등 다양한 상황에서 활용된다. 하지만 잘못 사용하면 성능 문제를 유발할 수 있으므로 필요할 때 적절히 사용하는 것이 중요하다.