클로저

클로저는 자바스크립트 개념에서 난해하기로 유명한 개념 중 하나이다.
딥하게 이해하기에 너무 난해하니 핵심 키워드로 함수가 선언된 렉시컬 환경으로 이해한다.

const x = 1;

function outFn(){
  const x = 10;
  function innerFn(){
    console.log(x);  // 10
  }
  innerFn();
}
outFn();

전역 변수 x가 선언되고 outFn() 안에 innerFn() 내부 함수로 선언되었기 때문에
outFn() 변수를 참조한다.


렉시컬 스코프

자바스크립트는 함수를 어디서 호출했는지가 아닌, 함수를 어디에서 정의했는지에 따라 상위 스코프가 정해진다. 이를 렉시컬 스코프라 한다.

const x = 1;

function outFn(){
  const x = 10;
  const inner = function () { console.log(x); }
  return inner;
}
// outFn 호출하면 inner 반환
// 그리고 outFn 실행 컨텍스트는 실행 컨텍스트 스텍에서 팝되어 제거
const innerFn = outFn();
innerFn();	// 10

외부 함수보다 중첩 함수가 더 오래 유지되는 경우, 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저라 한다. (죽은애 계속 참조🥺)

outFn()는 반환하고 생명 주기가 종료 후 실행 컨텍스트 스텍에서 제거되지만 outFn()의 렉시컬 환경까지 소멸하는 것은 아니다.

👀 부정문으로 기억하기

반대로 이야기하면 중첩 함수에서 상위 스코프를 참조하지 않으면, 메모리 낭비로 인해 자바스크립트에서는 상위 스코프를 기억하지 않는다. 따라서 중첩 함수이지만 스코프 참조가 없다면 클로저가 아니다.

  • 외부 함수 안에 중첩함수의 생명주기가 짧을때에도 클러저에 부합하지 않는다.

🙌 클로저 정의

클로저는 중첩 함수가 상위 스코프의 식별자를 참조하고 있고, 중첩 함수가 외부 함수보다 생명주기가 길때 클로저라 한정한다.


클로저의 활용

클로저는 상태를 안전하게 보호하고 특정 함수에게만 상태 변경 및 안전하게 유지하기 위해 사용한다. 상태를 안전하게 변경하고 유지할 수 있는 예제를 살펴보자

// 카운트 상태 변경
const increase = (function()) {
  let num = 0;
  // 클로저
  return function () {
    return ++num;
  };
}());

console.log(increase());  // 1
console.log(increase());  // 2

즉시실행 함수는 실행되고 소멸되지만 반환된 클로저 때문에 increase 변수가 호출될 때마다 num은 증가되고, 렉시컬 환경을 기억하고 있기 때문에 어디서 호출하든지 참조하고 변경할 수 있다.

profile
발로하는 코딩 정리기

0개의 댓글