관리 메뉴

Dev Blog

24. 클로저 본문

Tech Books/Javascript_Modern JS Deep dive

24. 클로저

Nomad Kim 2023. 2. 20. 21:02

 

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

클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.

24.1 렉시컬 스코프

자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 

함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다. 이를 렉시컬 스코프(정적 스코프)라 한다.

렉시컬 환경은 자신의 외부 렉시컬 환경에 대한 참조_Outer Lexical Environment Reference 를 통해 상위 렉시컬 환경과 연결된다. 

이것이 바로 스코프 체인이다.

렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 저장할 참조값, 

즉 상위 스코프에 대한 참조는 함수 정의가 평가되는 시점에 함수가 정의된 환경(위치)에 의해 결정된다. 

 

24.2 함수 객체의 내부 슬롯 [[Environment]]

함수는 자신의 내부 슬롯 [[Environment]]에 자신이 정의된 환경, 즉 상위 스코프의 참조를 저장한다.

함수 정의가 평가되어 함수 객체를 생성하는 시점은 함수가 정의된 환경, 즉 상위 함수(또는 전역 코드)가 평가 또는 실행되고 있는 시점이며, 이때 현재 실행 중인 실행 컨텍스트는 상위 함수(또는 전역 코드)의 실행 컨텍스트이기 때문이다.

함수 객체는 내부 슬롯 [[Environment]]에 저장한 렉시컬 환경의 참조, 즉 상위 스코프를 자신이 존재하는 한 기억한다.

 

위 예제의 foo 함수 내부에서 bar 함수가 호출되어 실행 중인 시점의 실행 컨텍스트는 아래와 같다.

24.3 클로저와 렉시컬 환경

외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 

이러한 중첩 함수를 클로저_closure 라고 부른다.

모든 함수가 기억하는 상위 스코프는 함수를 어디서 호출하든 상관없이 유지된다. 따라서 함수를 어디서 호출하든 상관없이 함수는 언제나 자신이 기억하는 상위 스코프의 식별자를 참조할 수 있으며 식별자에 바인딩된 값을 변경할 수도 있다.

outer 함수의 렉시컬 환경은 inner 함수의 [[Environment]] 내부 슬롯에 의해 참조되고 있고

inner 함수는 전역 변수 innerFunc에 의해 참조되고 있으므로 가비지 컬렉션의 대상이 되지 않기 때문에

outer 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거되지만 outer 함수의 렉시컬 환경까지 소멸하는 것은 아니다. 

outer 함수가 반환한 inner 함수를 호출()하면 inner 함수의 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 푸시된다.

중첩 함수 inner는 외부 함수 outer보다 더 오래 생존했다.

외부 함수보다 더 오래 생존한 중첩 함수는 외부 함수의 생존 여부(실행 컨텍스트의 생존 여부)와 상관없이 자신이 정의된 위치에 의해 결정된 상위 스코프를 기억한다.

 

중첩 함수가 상위 스코프의 식별자를 참조하고 있고 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에 한정하는 것이 일반적이다.

클로저에 의해 참조되는 상위 스코프의 변수(위 예제의 경우 foo 함수의 x 변수)를 자유 변수_free variable라고 부른다.

클로저_closure란 함수가 자유 변수에 대해 닫혀있다closed라는 의미다. 자유 변수에 묶여있는 함수 라고 할 수 있다.

'Tech Books > Javascript_Modern JS Deep dive' 카테고리의 다른 글

26. ES6 함수의 추가 기능  (0) 2023.02.20
25. 클래스  (0) 2023.02.20
23. 실행 컨텍스트  (0) 2023.02.19
22. this  (0) 2023.02.19
21. 빌트인 객체  (0) 2023.02.08
Comments