Chapter 24 클로저
in Frontend / Js / Javascript
Closures
- 오 프언 리뷰느낌쓰,,
- JS 한정이 아니기에 ECMAScript 에 등장 X
Closure = function + lexical environment of function (when declared) - MDN
24.1 렉시컬 스코프
- recap
- JS Engine: 어디서 호출이 아닌, 어디에 정의되었는지에 따라 상위 스코프 결정
- \(\rightarrow\) 정적 스코핑 (lexical/static scoping)
24.2 함수 객체의 내부 슬롯 [[Environment]]
- 함수 객체가 생성될 때, 함수가 정의된 환경을
[[Environment]]
내부 슬롯에 저장- => 상위 스코프를 여기다 저장함
- => 상위 스코프 참조 = 현재 실행 중인 실행 컨텍스트의 렉시컬 환경, because 생성 시점에는 상위 함수가 평가/실행중이기 때문
24.3 클로저와 렉시컬 환경
const x = 1;
function outer() {
const x = 10;
const inner = function () {
console.log(x); // 평가식이기에 runtime에 실행됨
};
return inner;
}
const innerFunc = outer();
innerFunc(); // 10
outer
은inner
를 반환하고 (life cycle) 종료outer
의 실행 컨텍스트는 스택에서pop
x
역시 생명주기 마감
BUT,
inner
은 어떻게x
접근 가능한가?outer
의 렉시컬 환경을 기억하고 있음inner
가 호출되면,outer
의 렉시컬 환경을 참조하여x
를 찾음
📌 외부함수보다 중첩함수가 더 오래 유지되는 경우
- 중첨함수는 이미 생명주기가 종료된 외부함수의 변수에 접근 가능
- 이러한 중첩함수를 클로저라고 부름
WHY?
- 위 실행 컨텍스트가 스택에서 pop 되지만 환경까지 소멸되는 것은 아님!
inner
의[[Environment]]
에 의해 참조 -> GC 대상 X
이론적으로 JS의 모든 함수는 클로저지만, 딱히 그렇게 부르진 않음
CASES::
- 상위 스코프의 어떤 식별자도 참조하지 않는 함수는 클로저라고 부르지 않는다
- modern JS 는 최적화를 통해 상위스코프를 기억하지 않음 (메모리 관리)
- 외부함수보다 생명주기가 짧은 중첩함수는 클로저라고 하지 않는다
외부함수가 종료되면, 중첩함수도 종료되기 때문
클로저의 경우, 상위 스코프 중의 참조하고 있는 식별자만을 기억하는 것이 대부분 (최적화)
자유 변수 (free variable): 클로저가 기억하는 상위 스코프의 변수
- 클로저란, 함수가 자유 변수에 대해 닫혀있는 것
- aka, 자유 변수에 묶여있는 함수
24.4 클로저의 활용
- 클로저: 상태를 안전하게 변경하고 유지하기 위해 사용
- 상태를 안전하게 은닉 (information hiding)
- 특정 함수에게만 상태 변경 권한 부여