Closure

민겸·2022년 10월 23일
0

JavaScript

목록 보기
12/20
post-thumbnail

이 글은 공식 문서 MDN을 기반으로 작성되었습니다.

클로저

클로저는 함수와 그 함수가 선언될 때 만들어지는 어휘적 환경(Lexical Environmnet)의 조합이다.

클로저를 이해하기 위해서는 자바스크립트가 변수의 유효범위(Lexical Scope)를 어떻게 지정하는지(Lexical Scoping) 알아야 한다.

Lexical Scoping

function A_Func(인자A) {
	var 지역_변수A = "Hi";
  
  	function B_Func() {
    	alert(지역_변수A);
    }
  
  	B_Func();
}

A_Func();

위의 코드를 실행하면,

  1. A_Func 함수가 선언된다. A_Func 함수는 하나의 인자를 받으며, 지역 변수(A) 하나와 중첩 함수(B_Func) 하나를 생성한다.
  2. 중첩 함수 B_Func()는 A_Func 의 내부 함수이므로, A_Func 함수 안에서만 실행될 수 있다. 여기서 주의할 점은 B_Fun()함수는 지역 변수를 가지고 있지 않다는 것이다. 지역 변수를 가지고 있지 않지만, 외부 함수인 A_Func함수의 지역 변수에 접근할 수 있기 때문에 B_Fun()함수 역시 지역변수A에 접근할 수 있다.
  3. 결과는 A_Func함수 실행 -> 지역 변수, 내부 함수 생성 후 실행 -> 내부 함수에서 외부 함수의 지역 변수에 접근해 alert("Hi")를 실행한다.

이것은 Lexical Scoping을 보여주는 한 예시이다.

쉽게 말해서, 함수 내부에서 지역 변수가 선언될 때, Lexical Scoping이 일어난다. 이 Lexical Scoping은 지역 변수의 사용 가능해지는 위치가 지역 변수의 선언된 위치에 따라 다르다는 것을 의미한다.
즉, 내부 함수는 외부 함수에서 선언된 변수에 접근할 수 있다.


이제 다음 예를 보자.

function A_Func(인자A) {
	var 지역_변수A = "Hi";
  
  	function B_Func() {
    	alert(지역_변수A);
    }
  
  	return B_Func;
}

const 전역_변수 = A_Func();

전역_변수();

위 코드는 이전에 있던 코드와 동일하게 작동한다. 차이점이 있다면, B_Func함수가 A_Func함수 안에서 실행되기 전에 리턴되어 전역_변수에 할당된다는 것이다.

일반적으로, 어떤 함수 내부에 지역 변수가 있으면 그 지역 변수는 함수가 처리되는 동안만 존재해야 한다. 그러므로, B_Func이 리턴되면 A_Func은 종료되며 지역_변수A에 더 이상 접근할 수 없어야 한다.

하지만, 자바스크립트는 다르다.
자바스크립트는 함수를 생성하면 그 함수의 클로저가 형성되기 때문이다. 지금 같은 경우, B_Func 함수를 리턴하고 있는데 B_Func 함수가 클로저를 형성하기 때문이라고 볼 수 있다. 클로저는 함수와 함수가 선언된 Lexical Environment의 조합이다. 이 렉시컬 환경은 클로저가 형성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다. 그리고 위의 예시에서 이 모든 지역 변수에는 지역_변수A가 포함된다.

  1. 함수 A_Func전역_변수가 선언된다. 여기서 전역_변수는 함수 A_Func의 반환값인 B_Func을 참조한다.

  2. B_Func은 선언될 때 Lexical Scoping이 발생함에 따라, 외부 함수의 지역_변수A를 가진 Lexical Environment를 참조하고 있다.

  3. 이에 따라, 참조 -> 참조를 통해 전역_변수()를 실행하면, 지역_변수A는 사용할 수 있는 상태로 유지되어 alert("Hi")가 실행된다.


좀 복잡하지만, 겉핥기 식으로라도 개념이 잡혀가는 것 같다... 다룰 만한 내용들이 더 있지만 시간 관계상 나중에 다뤄보자.

profile
기술부채상환중...

0개의 댓글