TIL 19. JS closure

rahula·2021년 5월 20일
0

javascript

목록 보기
11/15
post-thumbnail

closure

closure?

closure은 functional programming language에서 등장하는 보편적인 특성이다.

Closed over variable environment 혹은 persistent lexical scope referrenced data라고도 불린다.

closure을 설명하는 여러가지 방법이 있다.

자신을 내포하는 함수의 execution context에 접근할 수 있는 함수.
함수가 특정 scope에 접근할 수 있도록 의도적으로 그 scope에서 정의하는 것.

한 마디로, closure은 어떤 함수에서 그것의 바깥 변수값을 기억하는 것이다. 클로저는 함수로 하여금 지속적인 메모리를 가질 수 있도록 한다.

const outer = () => {
  let a = 0;
  // 내부함수
  const inner = () => {
    // 외부함수 outer의 변수 a를 참조
    console.log(a); // 0
    a++;
    console.log(a); // 1
  };
  inner();
  console.log(a); // 1
};

outer();

lexical environment와 closure

A closure is the combination of a function and the lexical environment within which that function was declared. - MDN

함수와 그 함수가 선언될 당시의 lexical environment, 즉 outerEnvironmentReference의 상호관계에 따른 현상.
내부 함수에서 외부 변수를 참조하는 경우에 한해서만 이 상호관계가 의미가 있다.

어떤 함수에서 선언한 변수를 참조하는 내부함수에서만 발생하는 현상.
내부에서 호출한 함수가 referencing하고 있는 동안에는, 해당 변수는 garbage collector의 수집 대상이 되지 않는다. 이는 외부함수가 끝난 뒤에도 내부 함수에서는 해당 scope가 유지된다는 거.

참조 카운트와 garbage collector

closure은 정말 메모리의 역할이다.

execution context가 유지되거나 closure이 주어지는 한, 변수들의 주솟값은 garbage collector의 대상이 되지 않는다. 메모리 상에 남아있다.

함수의 execution context가 종료되면 LexicalEnvironment에 저장된 식별자들에 대한 참조를 지운다. 그러면 식별자에 저장되어있던 각각의 주솟값들은 이제 자신을 참조하는 변수가 하나도 없게 되므로 garbage collector의 수집대상이 된다. 다시 말해 메모리 상에서 지워진다는 것.

내부 함수 호출

그렇다면 함수가 종료된 이후에도 내부 함수를 호출할 수 있게 만들면 어떻게 될까??

garbage collector는 어떤 값을 참조하는 변수가 하나라도 있따면 그 값은 수집 대상에 포함시키지 않는다. 외부함수의 실행이 종료되더라도 내부함수가 호출될 가능성이 있다면, 해당 내부함수에서 참조하는 식별자의 주솟값은 메모리상에서 지우지 않는다는 거!

즉 closure이란 어떤 함수에서 선언한 변수를 참조하는 내부함수에서만 발생하는 현상인데, "외부 함수의 LexicalEnvironment가 garbage collecting당하지 않는 현상"을 뜻한다.
어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 execution context가 종료된 이후에도 변수 a가 사라지지 않는 현상.

실제적인 closure은 함수라기보다는 'closure 현상에 의해 메모리에 남겨진 변수들의 집합'을 지칭하는 것으로 이해하는 것이 더 정확하다.

return 없이도 closure은 발생할 수 있다.

web API의 callback으로써 넘기는 것도 똑같다! 결국 외부함수의 변수를 참조하는 내부함수가 callback으로써 호출되는 것이므로, 여기서 참조하는 주솟값은 메모리상에서 지워지지 않는다.

profile
백엔드 지망 대학생

0개의 댓글