본문 바로가기
필수 개발지식/JS

[JS] 클로저(Closure)란?

by 코딩하는짱구 2023. 7. 26.
반응형

✅ 클로저(Closure)란?

  • 정의 : 함수와 함수가 선언된 어휘적 환경의 조합
  • 함수와 그 함수가 만들어진 환경(Lexical environment)을 함께 묶어서 일종의 '패키지'로 만드는 것
  • 함수가 자신이 만들어진 환경을 기억하고 있는 것
  • 함수가 독립적으로 동작하면서도 외부 변수에 접근이 가능하게 만들어줌
  • 목적 : 데이터 은닉과 캡슐화를 구현, 상태유지, 콜백함수, 반복문에서의 변수 유지

 

🔍예시1) 클로저예시

function outerFunction() {
  let outerVariable = 10;

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

//closure없이 실행시 10이 반환되지 않는 이유
//outerVariable은 innerfunction의 외부 환경에 있는 변수, 클로저의 핵심적인 개념
//즉 outer에서 반환된 inner를 호출하려면 outer()의 결과를 변수에 할당한 후에, 해당 변수를 실행해야한다.
console.log(outerFunction());
// Output: [Function: innerFunction]

//outerfunction()을 호출하여 반환된 결과값 innerFunction 을 closureExample이라는 변수에 할당한다
//변수에 할당한 함수를 나중에 실행하려면 함수 이름 다음에 ()를 붙여서 호출
const closureExample = outerFunction();
closureExample();
// Output: 10

설명 : innerFunction은 outerFunction내부에 정의 되어있고 자신이 만들어진 outerFunction의 환경을 기억하고 있으므로 outerVariable에 접근하여 값을 출력할 수 있다. 

 

 

 

🔍예시2) 클로저를 통해 콜백함수를 실행

function outerFunction() {
  let outerVariable = 10;

  function innerFunction(callback) {
    setTimeout(function () {
      console.log(outerVariable); // 콜백 함수에서 outerVariable에 접근
      callback();
    }, 1000);
  }

  return innerFunction;
}

const closureExample = outerFunction();

closureExample(function () {
  console.log('Callback function executed!');
});

설명 : innerFunction은 콜백함수를 인자로 받아서 실행된다. closureExample함수를 호출하면 innerFunction이 반환되고, innerFunction은 자신이 만들어진 환경을 기억하므로 outerVaribale에 접근하여 값을 출력할 수 있다. 

 

목적 : 콜백함수가 클로저를 통해 자신이 만들어진 스코프의 변수에 접근할 수 있으므로, 비동기 작업에서 상태 유지나 외부 변수를 활용할 수 있다.

 

 

 

🔍예시3) 비슷한 코드를 재사용하는 예시

// 클로저를 활용하여 덧셈, 뺄셈, 곱셈, 나눗셈 함수를 생성하는 함수
function createMathOperations(x) {
  return {
    add: function (y) {
      return x + y;
    },
    subtract: function (y) {
      return x - y;
    },
    multiply: function (y) {
      return x * y;
    },
    divide: function (y) {
      return x / y;
    },
  };
}

// 클로저를 사용하여 10을 기준으로 한 다양한 수학 연산을 수행하는 객체 생성
const mathWithTen = createMathOperations(10);

console.log(mathWithTen.add(5)); // Output: 15
console.log(mathWithTen.subtract(3)); // Output: 7
console.log(mathWithTen.multiply(2)); // Output: 20
console.log(mathWithTen.divide(2)); // Output: 5

 

 

🔍예시4) 반복문에서 변수를 유지하는 예시

function createPrintFunction(i) {
  return function() {
    console.log(i);
  };
}

for (var i = 0; i < 5; i++) {
  const print = createPrintFunction(i);
  setTimeout(print, 1000);
}

설명 : 클로저 함수는 i값을 기억하고 있으며 createPrintFunction을 호출하면 클로저가 반환되는데 이때 'i'의 값이 각각의 클로저에 포착됌. 

 

 

 

 

✅ 클로저(Closure)사용의 장단점

장점

  • 데이터 은닉과 정보 보호 : 변수를 함수 스코프에 은닉함으로써 외부에서 직접 접근이 불가
  • 상태유지 : 클로저는 함수가 만들어진 환경을 기억하므로 함수 호출 사이에 상태를 유지할 수 있다
  • 비동기 작업 및 콜백함수 : 비동기작업에서 콜백함수를 클로저로 사용하여 비동기 작업이 완료된 후에 해당작업의 결과 처리
  • 모듈패턴을 구현할 수 있다. (모듈패턴 : 

 

단점

  • 메모리관리 : 클로저가 참조하는 변수가 필요하지 않을 때에도 클로저가 계속 메모리에 남을 수 있다
  • 복잡성 : 클로저로 인해 코드가 더 복잡해지고 가독성이 떨어질 수 있다
  • 변수 유지의 부작용 
반응형