[하루 30분 모던 자바스크립트 딥 다이브] 클로저란 무엇인가

💪렉시컬 스코프

렉시컬 환경의 “외부 렉시컬 환경에 대한 참조”에 저장된 참조값. 즉 상위 스코프는 평가되는 시점에 함수가 정의된 환경(위치)에 의해 결정된다.

💪함수 객체 내부슬롯 [[Environment]]

함수는 내부슬롯 [[Environment]]에 자신이 정의된 환경, 즉 상위 스코프를 저장한다. (현재 실행중인 실행 컨텍스트의 렉시컬 환경)

함수 객체 내부슬롯 [[Environment]]에 저장된 현재 실행중인 실행 컨텍스트의 렉시컬 환경의 참조가 상위 스코프이다. 또 호출 되었을 때 생성된 함수 렉시컬 환경의 “외부 렉시컬 환경에 대한 참조”에 저장될 참조 값이다

즉 함수는 내부 슬롯 [[Environment]]가 있고, 함수가 정의 될 때 상위 스코프를 저장. 저장된 값은 호출이 되어도 바뀌지 않고 따라다닌다.

💪클로저란 무엇일까

const x = 1;

function outer() {
	const x = 10;
	const inner = function () {console.log(x);}
	return inner;
}
const innerFunc = outer()
innerFunc() // 10

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

외부 함수의 실행 컨텍스트는 스택에서 제거되지만 외부 함수의 렉시컬 환경은 소멸되지 않는다.

가비지 컬렉터는 참조하고 있는 메모리 공간을 해제하지 않는다.

상위 스코프의 어떤 식별자도 참조하지 않는 함수는 클로저가 아니다. (자바스크립트의 모든 함수는 상위스코프를 기억하므로 이론적으로 모두 클로저가 될 수 있다.)

대부분의 모던 브라우저는 최적화를 위해 상위스코프의 식별자 중 클로저가 참조하고 있는 식별자만 기억한다.

클로저에 의해 참조되고 있는 변수를 “자유 변수”라 부르고, 클로저란 “함수가 자유변수에 닫혀있다”는 의미이다.

클로저는 최적화가 잘 되어 있어 메모리 낭비를 하지 않는다. 따라서 적극 권장되는 기능이다.