[TIL]JavaScript_클로저

Sohee Yeo·2023년 6월 14일
0
post-thumbnail

클로저(Closure)

클로저는 함수와 해당 함수가 선언된 렉시컬 환경의 조합이다. 외부 함수의 실행이 종료된 후에도 중첩 함수는 외부 함수의 변수를 기억하여 참조할 수 있다. 이러한 중첩 함수를 클로저라고 한다.

📌 렉시컬 스코프
함수가 정의된 위치에 의해 상위 스코프가 결정되는 스코프

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

함수 객체를 생성할 때 자신이 정의된 위치에 의해 결정된 상위 스코프의 참조를 자신의 내부 슬롯 [[Environment]]에 저장한다.

const x = 1;

function funcOne() {
	const x = 5;
  
// 함수의 호출 위치와 상위 스코프는 아무런 관계가 없다.
	funcTwo();
};

function funcTwo() {
  // 함수 funcTwo는 자신의 상위 스코프를 내부슬롯 [[Environment]]에 저장하여 기억한다.
 console.log(x);
};

funcOne(); // 1
funcTwo(); // 1

클로저와 렉시컬 환경

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

const x = 1;

function outer() {
	const x = 5;
  
  	// 중첩 함수 inner은 클로저
  	const inner = function() {
      console.log(x);
    };
	return inner;
};

// 함수 outer을 호출하면 중첩 함수 inner을 반환하고, outer 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거된다.
const innerFunc = outer();
innerFunc(); // 5

위의 예제에서, 함수 outer의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거되지만, outer의 렉시컬 환경까지 소멸하는 것은 아니다. 함수 outer의 렉시컬 환경은 함수 inner의 [[Environment]] 내부 슬롯에 의해 참조되고 있고 inner은 전역 변수 innerFunc에 의해 참조되고 있다.
📢 클로저에 의해 참조되는 상위 스코프의 변수(예제에서 outer 함수의 x)를 자유 변수라고 부른다. 클로저란 자유 변수에 묶여있는 함수라고도 할 수 있다.

클로저의 활용

상태(state)를 안전하게 은닉, 특정 함수에게만 상태 변경 허용
함수가 호출될 때마다 횟수를 누적하여 출력하는 카운터를 만들어보자.

let num = 0;

const increase = function() {
	return num++;
};

console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3

카운트 상태(num)는 increase 함수가 호출되기 전까지 변경되지 않아야 하고, 카운트 상태(num)는 increase 함수만이 변경할 수 있어야 한다. 하지만 위의 예제에서 카운트 상태가 전역에서 관리되고 있으므로 누구나 접근할 수 있고 변경할 수 있는 위험이 있다.

// 카운트 상태 변경 함수
const increase = (function() {
  	let num = 0;
  	// 클로저
	return function() {
    	return num++
    };
}());

console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3

위의 예제에서, 즉시 실행 함수가 반환한 클로저는 카운트 상태를 유지하기 위한 자유 변수 num을 어디서 호출하든지 참조하고 변경할 수 있다. 또한 num 변수는 은닉된 private 변수이므로 의도되지 않은 변경을 걱정하지 않아도 된다.

정리

  • 클로저는 외부 함수의 실행이 종료된 후에도 외부 함수의 변수를 기억하여 참조할 수 있는 함수이다.
  • 외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다.
  • 클로저는 상태(state)를 은닉하고 특정 함수에게만 상태 변경을 허용하여 상태를 안전하게 변경하고 유지하기 위해 사용한다.



참고

모던 자바스크립트 Deep Dive (도서)

profile
실패에 무딘 사람. 프론트엔드 개발자를 꿈꿉니다

0개의 댓글

관련 채용 정보