[딥다이브] 24장 클로저

주니·2023년 4월 9일
0

딥다이브

목록 보기
15/20

24. 클로저

  • 클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.
  • JS엔진은 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다. 이를 렉시컬 스코프(정적 스코프)라고 한다.
  • 중첩 함수 클로저: 외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩함수는 이미 생명 주기가 종료한 외부함수의 변수를 참조할 수 있다.
  • 실행 컨텍스트 스택에서 제거되어도 렉시컬 환경까지 소멸하는 것은 아니다.
  • 상위 스코프의 어떤 식별자도 참조하지 않는 함수는 클로저가 아니다.
  • 클로저는 중첩 함수가 상위 스코프의 식별자를 참조하고 있고 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에 한정하는 것이 일반적이다.
  • 클로저에 의해 참조되는 상위 스코프의 변수를 자유 변수라고 부른다.
  • 클로저란 ‘함수가 자유 변수에 대해 닫혀있다’라는 의미이다. ⇒ 자유 변수에 묶여있는 함수
  • 클로저는 JS의 강력한 기능으로, 필요하다면 적극 활용해야 한다.

클로저의 활용

  • 상태를 안전하게 변경하고 유지하기 위해 사용한다.
  • 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용
// 함수를 반환하는 고차 함수
// 이 함수는 카운트 상태를 유지하기 위한 자유 변수 counter를 기억하는 클로저를 반환한다.
const counter = (function () {
	// 카운트 상태를 유지하기 위한 자유 변수
	let counter = ;

	// 함수를 인자로 전달받는 클로저를 반환
	return function (aux) {
		//인수로 전달받은 보조 함수에 상태 변경을 위임한다.
		counter = aux(counter);
		return counter;
	};
}());

// 보조 함수
function increase(n) {
	return ++n;
}

function decrease(n) {
	return --n;
}

// 보조 함수를 전달하여 호출
console.log(counter(increase)); // 1
console.log(counter(increase)); // 2
console.log(counter(decrease)); // 1
console.log(counter(decrease)); // 0

캡슐화와 정보 은닉

캡슐화: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 말한다.

정보 은닉: 객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용

  • 적절치 못한 접근으로 객체의 상태가 변경되는 것을 방지해 정보를 보호
  • 객체 간의 상호 의존성, 즉 결합도를 낮추는 효과
  • JS 객체의 모든 프로퍼티와 메서드는 기본적으로 public

JS는 정보 은닉을 완전하게 지원하지 않는다. 인스턴스 메서드를 사용한다면 자유 변수를 통해 private를 흉내 낼 수는 있지만 프로토타입 메서드를 사용하면 이마저도 불가능해진다.

자주 발생하는 실수

클로저를 사용해 다음과 같이 원하는 결과값을 출력하는 코드를 작성할 수 있다.

const funcs = [];

for (let i = 0; i < 3; i++) {
	func[i] = function () { return i };
}

for (let i = 0; i < funcs.length; i++) {
	console.log(funcs[i]()); // 0 1 2
}

0개의 댓글