클로저

카오·2021년 1월 30일
0

클로저는 함수형 프로그래밍 언어에서 등장하는 보편적인 특성.
의외로 쉬운 개념이지만 문장만 놓고 보면 이해하기 쉽지 않음 1


클로저를 나타내는 다양한 표현

  • 자신을 내포하는 함수의 컨텍스트에 접근할 수 있는 함수 - 더글라스 크록포드
  • 함수가 특정 스코프에 접근할 수 있도록 의도적으로 스코프를 정의하는 것 - 에단 브라운
  • 함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 잇는 함수 - 존 레식
  • 자유변수가 있는 함수와 자유변수를 알 수 있는 환경의 결합 - 에릭 프리먼
  • 자신의 생성될 때의 스코프에서 알 수 있었던 변수들 중 언젠가 자신이 실행될 때 사용할 변수들만을 기억하며 유지시키는 함수 - 유인동

MDN(Mozila Developer Network)에 클로저

함수와 그 함수가 선언될 당시의 lexical environment의 상호관계에 따른 현상

렉시컬 스코프?

var x =1; // 변수x 선언
function fooFunc(){
	var x = 10;
  	barFunc();
}

function barFunc(){
	console.log(++x);
}
fooFunc(); // x = ?
barFunc(); // x = ?

위 코드 실행결과는 함수 barFunc의 상위 스코프에 따라 결정되고 2가지로 생각할 수 있다.

  1. 함수를 어디서 호출시점에 따른 상위 스코프 결정 -> ( fooFunc, 전역 )
  2. 함수를 어디서 선언시점에 따른 상위 스코프 결정 -> ( 전역 )

프로그래밍 언어는 이 두가지 방식 중 하나의 방식으로 함수의 상위 스코프를 결정하고
첫번째 방식을 동적 스코프 두번째 방식을 렉시컬 스코프 또는 정적 스코프라고 한다.

실행컨텍스트의 관점에서 스코프 체인이 바인딩한 객체는 곧 렉시컬 스코프가 된다.

상호관계?

function fooFunc(){
	var x = 1
    var barFunc = function(){ 
    	return ++x;
    }
    return barFunc;
}
// fooFunc를 호출하면 내부 barFunc이 반환되고
// 함수 fooFunc의 실행컨텍스트는 소멸된다.
var barFunc = fooFunc();
console.log(barFunc()); // 2
console.log(barFunc()); // 3

위 코드를 fooFunc은 내부 barFunc을 반환하고 콜(실행컨텍스트)스택에서 제거되고 fooFunc에 선언된 변수 x또한 유효하지 않게되어 접근할 수 있는 방법이 없어진다.
그러나 코드의 동작을 보면 제거된 fooFunc의 지역변수 x가 부활이라도 한 듯 동작하고 있다.

자신을 포함하고 있는 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라고 부른다.

조금더 간단히 말하면 클로저는 자신이 생성될 때의 환경을 기억하는 함수

버튼 상태제어를 위한 클로저 활용

var button = document.createElement("button");
button.textContent="click";
var toggle = (function(){
	var isBlack = false;
	return function(){
    	this.style.color = isBlack ? 'black' : 'red';
      	isBlack = !isBlack; 
    }     
})();
button.addEventListener("click", toggle )
document.body.append(button)

클로저와 메모리 관리

클로저는 어떤 필요에 의해 함수의 지역변수를 의도적으로 사용하기 때문에 관리를 잘하지 않으면 메모리 누수가 발생할 수 있다. 필요성이 없어진 클로저는 참조카운트 제거를 위해 null 혹은 undefined를 할당해 준다.

button.removeEventListener("click", toggle )
toggle = null;

1 : 책에 그렇게 적혀있다는 글입니다.

profile
front-develop

0개의 댓글