본문 바로가기

개발에 도움이 되는/JavaScript

클로저(Closure)

- 클로저 (Clousure)

MDN에서의 정의 : "함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합"

 

모던 자바스크립트 Deep Dive에서의 정의 : "반환된 내부 함수가 자신이 선언됐을 때의 환경(렉시컬 환경)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수"

즉, 자신이 생성될 때의 렉시컬 환경을 기억하는 함수

 

내 나름대로의 정의 : 외부 변수를 품고 있는 함수, 함수는 원래 호출 후 실행 완료되면 CallStack에서 Pop되고, 선언된 변수 메모리는 GC에 의해 제거되어야 하지만 참조하고 있는 변수가 있어 제거되지 못한 상태라고 생각한다.

 

 

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}

/**
 *  함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
 *  그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
 */
var inner = outerFunc();
inner(); // 10

 

클로저에 의해 참조되는 외부 함수의 변수 즉 outerFunc 함수의 변수 x를 자유 변수(Free Variable)라고 부른다.

클로저라는 이름은 자유 변수에 함수가 닫혀있다라는 의미로 의여하면 자유 변수에 엮여있는 함수라는 뜻이다.

 

실행 컨텍스트의 관점에 설명하면, 내부함수가 유효한 상태에서 외부함수가 종료하여 외부함수의 실행 컨텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성 객체(Activation Object)(변수, 함수 선언 등의 정보를 가지고 있다)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프 체인을 통해 참조할 수 있는 것을 의미한다.

즉 외부함수가 이미 반환되었어도 외부함수 내의 변수는 이를 필요로 하는 내부함수가 하나 이상 존재하는 경우 계속 유지된다. 이때 내부함수가 외부함수에 있는 변수의 복사본이 아니라 실제 변수에 접근한다는 것에 주의하여야 한다.

이를 그림으로 표현하면 아래와 같다.

 

 

이렇게 클로저는 닫혀있는 변수를 이용하여 현재 상태를 기억하고 변수를 Private하게 사용할 수 있다.

전역 변수로 선언하여 사용할 경우 다른 곳에서 접근의 위험성이 있는데 그런 문제가 없어진 것이다.

 

 

- 예제

function closure() {
  let cnt = 0;
  function cntPlus() {
    cnt += 1;
  }
  function printCnt() {
    console.log(cnt);
  }
  
  return{
    cntPlus,
    printCnt,
  }
}

const cntClosure = closure();
cntClosure.cntPlus();
cntClosure.printCnt(); // 1

위 코드를 확인해보면, 저렇게 cntClosure라고 선언 후 closure 함수를 할당하게 되면 return 값으로 설정한 함수들을 받게 되고, 아래 cntClosure.cntPlus(), cntClosure.printCnt()와 같이 호출해야만 은닉되어 있는 변수에 접근할 수 있다.

 

 

참고 사이트 : https://poiemaweb.com/js-closure

반응형

'개발에 도움이 되는 > JavaScript' 카테고리의 다른 글

원시 자료형, 참조 자료형  (0) 2022.04.05
this  (0) 2022.04.03
스코프(Scope)  (0) 2022.02.27
실행 컨텍스트(Execution Context)  (0) 2022.01.15
호이스팅(Hoisting)  (1) 2022.01.05