[JS] Closure

김영훈·2021년 12월 7일
1

Javascript Basic

목록 보기
2/4

Closure (클로저)란?

MDN에서 정의한 클로저다.

“A closure is the combination of a function and the lexical environment within which that function was declared.”
클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.

사실 이 정의만 보고서는 제대로 이해가 안간다.
그래서 코드로 알아보도록 하자

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

var inner = outerFunc(); 
inner(); // 10

스코프는 함수를 어디에 선언했는지에 따라 결정된다.
이를 렉시컬 스코핑(Lexical scoping)라 한다.

innerFunc의 상위 스코프는 outerFunc이며 outerFunc의 상위 스코프는 전역 스코프가 된다.
이떄 innerFunc는 자신의 상위스코프인 outerFunc, 전역에 접근할 수 있다.

다시 MDN 정의로 돌아가보면 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란 내부 함수가 선언됐을 때의 스코프를 의미한다. 즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.

더 간단히 말하면 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있다.

그렇다면 클로저는 어디서 활용하는게 좋을까?

상태유지

클로저가 가장 유용하게 사용되는 상황은 현재 상태를 기억하고 변경된 최신 상태를 유지하는 것이다.

var toggleBtn = document.querySelector('.toggle');

var toggle = (function () {
  var isShow = false;

  // ① 클로저를 반환
  return function () {
    box.style.display = isShow ? 'block' : 'none';
        // ③ 상태 변경
    isShow = !isShow;
  };
})();

toggleBtn.onclick = toggle; // 클로저 할당

toggle은 함수를 반환하고 즉시 소멸한다. toggle은 렉시컬 환경에 속한 변수 isShow를 기억하는 클로저다.

이처럼 클로저는 상태가 변경되어도 최신 상태를 유지해야 하는 상황에 매우 유용하다.
만약 자바스크립트에 클로저라는 기능이 없다면 상태를 유지하기 위해 전역 변수를 사용할 수 밖에 없다.

전역 변수 사용 억제


var increase = (function () {
 // 카운트 상태를 유지하기 위한 자유 변수
  var counter = 0;
// 클로저를 반환
  return function () {
    return ++counter;
  };
}());


incleaseBtn.onclick = function () {
	count.innerHTML = increase();
};

즉시 실행 함수가 호출되며 ++counter가 할당되어있는 함수는 자신이 생성되었을 때의 렉시컬 환경(Lexical environment)을 기억하는 클로저다. 즉시실행함수는 호출된 이후 소멸되지만 즉시실행함수가 반환한 함수는 변수 increase에 할당되어 버튼 클릭시 호출된다.

변수 counter는 외부에서 직접 접근할 수 없는 private 변수이므로 전역 변수를 사용했을 때와 같이 의도되지 않은 변경을 걱정할 필요도 없기 때문이 보다 안정적인 프로그래밍이 가능




출처: 모던 자바스크립트 딥다이브 발췌

profile
개인적인 기록.

0개의 댓글