본문 바로가기
JavaScript

클로저 (Closure)

by whoyoung90 2022. 3. 30.
반응형

1.  클로저란?

외부함수 A에서 선언한 "지역변수 a를 참조하는 내부함수 B가 외부로 전달"될 경우
A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상(참조할 수 있는 현상)
지역변수를 참조하는 내부함수를 외부에 전달하면 클로저!
내부함수에서 외부 변수를 사용하면 클로저!

 

✅ 내부함수를 외부로 전달하는 방법은 함수를 return 하거나 콜백으로 전달

2.  일반함수의 경우?

outer함수의 실행 컨텍스트가 종료되기 전에 이미 inner함수의 실행 컨텍스트가 종료돼 있으므로
이후 별도로 inner함수를 호출할 수 없다.

 

일반 함수와 마찬가지로 outer의 Lexical Environment가 모두 가비지 컬렉팅 대상에 포함!
( inner가 먼저 종료되므로 outer의 Lexical Environment를 참조하는 대상이 없기 때문에 )

 

이미 실행결과를 반환하고 있으므로 outer함수의 실행 컨텍스트가 종료된 시점에는 a변수를 참조하는 대상이 없어진다. (클로저 X)

const outer = () => {
  let a = 1;
  const inner = () => {
    console.log(++a);
  };
  inner(); // inner함수 실행결과를 반환 (inner 실행컨텍스트 종료✅)
};
outer(); // 2
outer(); // 2 (inner는 더이상 호출 X)
outer(); // 2 (inner는 더이상 호출 X)
/* 클로저로 변환한다면? */
const outer = () => {
  let a = 1;
  const inner = () => {
    console.log(++a);
  };
  return inner; // inner함수를 반환
};
const closure = outer();
closure(); // 2
closure(); // 3
closure(); // 4

3.  그렇다면 클로저?

outer의 실행 컨텍스트가 종료된 후에도 inner함수를 호출할 수 있도록!

 

- 일반 outer함수는 return inner( ) => 실행결과를 반환! 이후 호출❌

- 클로저 outer함수는 return inner => inner호출시점을 outer함수 종료이후로 미룬다. 이후 호출⭕️

 

⭐️ outer함수의 실행 컨텍스트가 종료될 때, outer2 변수는 outer함수의 실행결과인 inner함수 자체를 참조
⭐️⭐️ 즉, outer2를 호출하면( ) 비로소 inner가 실행!

const outer = () => {
  let a = 1;
  const inner = () => {
    console.log(++a);
  };
  return inner; // inner함수를 반환
};
const outer2 = outer(); ⭐️
outer2(); // 2 inner함수를 여기서 실행 (inner 실행컨텍스트 종료✅) ⭐️⭐️
outer2(); // 3 inner함수를 여기서 실행 (inner 실행컨텍스트 종료✅)
outer2(); // 4 inner함수를 여기서 실행 (inner 실행컨텍스트 종료✅)
/* 다른 버전 */
const outer = (() => {
  let a = 1;
  const inner = function () {
    return console.log(++a);
  };
  return inner; // inner함수를 반환
})()
outer(); // 2
outer(); // 3
outer(); // 4

🚩 클로저일때 inner함수의 실행 시점에는 outer함수는 이미 종료된 상태인데 어떻게 outer함수의 L.E에 접근할 수 있을까?🤔

가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집대상에 포함시키지 않는다.

 

1.  outer함수가 실행 종료 시점에 inner함수를 반환

2.  inner함수는 언젠가 outer2를 실행함으로써 호출 가능성이 열려있는 것!!

3.  언젠가 inner함수의 실행 컨텍스트가 활성화 되면 outer함수의 L.E를 필요로 할 것이므로 수집대상에서 제외된다.

 

즉, 어떤 함수의 L.E는 이를 "참조"할 예정인 다른 실행 컨텍스트가 있는 한, 실행 종료 이후에도 가비지컬렉터 대상이 되지 않는다.

 

4.  정리

함수의 실행 컨텍스트가 종료된 후에도 Lexical Environment가 가비지 컬렉터의 수집 대상에서 제외되는 경우
지역변수를 참조하는 내부함수가 외부로 전달된 경우가 유일하다.

 

외부함수에서 선언한 지역변수를 참조하는 내부함수에서만 발생하는 현상 이란
외부함수의 Lexical Environment가 가비지컬렉팅 되지 않는 현상을 뜻한다.

반응형

댓글