[JS] 클로저

Yeong·2024년 10월 27일

클로저는 ‘함수’를 지칭하고 또 ‘그 함수가 선언된 환경과의 관계’의 개념이다.
클로저는 ‘자신이 선언될 당시의 환경을 기억하는 함수’이다.
클로저는 ‘내부함수가 외부함수의 context에 접근’할 수 있는 것을 가리킨다.

hector 내부의 spirit 변수를 참조하는 함수가 있기 때문에 이 spirit 변수는 삭제되지않고 heap 으로 옮겨진다.
heap에서는 garbage collector가 더이상 참조되지않는 데이터를 수거한다.

cooc 변수에 저장된 hector라는 함수가 프로그램에 남아있는 동안은 내부함수의 영혼이 사라지지않지만,
coco = null; 과 같이 해당 함수도 참조를 잃게 되면, 이제 그 영혼은 다음 garbage collection때 수거된다.

예시1

function delayLog(msg, time) {
	setTimeout(function(){
    	console.log(msg);}, time);
}

delayLog("Remember this!", 1000);

delayLog 함수가 실행된 직후, 이 함수의 정보는 콜스택에서 사라지게 되어있다. (해당 함수의 지역 변수 뿐만 아니라, msg와 time과 같은 매개변수들도 삭제됨)

하지만! 코드를 실행해보면 1초 후에 문자열이 그대로 출력된다 !!!

왜냐, 클로저에 의해 이 매개변수가 함수의 실행 이후에도 메모리상에 유지되어 있기 때문 !!!

예시2

function makeAdder(x) {
  return function(y) {
    return x+y;
  }
}

const add3= makeAdder(3);
console.log(add3(2));

함수 makeAdder(x)가 클로저를 이용해 내부 함수에서 x 값을 유지하면서 y를 매개변수로 받는 방식이다.
🧚 makeAdder(3)을 호출하면 x가 3으로 설정된 함수를 반환한다는 의미!

코드 실행 순서를 간단히 적어보자면,

  1. makeAdder(3);을 호출할 때, x가 3으로 설정된 상태에서 내부 함수 function(y) { return x + y; }를 반환한다.
    이 반환된 함수는 x = 3이라는 환경을 계속 기억하고 있는 클로저가 된다.

  2. const add3 = makeAdder(3); 에 의해 add3는 x=3 이 고정된 함수가 된다.

  3. add3(2);를 호출하면, add3 함수 내부에서 y는 2로 설정되고, x + y3 + 2로 계산돼서 5를 반환한다.

결과적으로, add3(2);에서 2는 y에 전달된다고 볼 수 있는데 클로저 덕분에 x는 3으로 기억된 채로 함수가 동작하는 것!!!

예시3

function outer() {
	let message = 'Hello! ';

	return function inner(name) { // inner함수는 클로저
		return message = message + name;
	}
}

let greeting = outer(); // 외부함수 호출. 변수 greeting은 inner 함수를 참조

console.log(greeting('Janet')); // Hello! Janet
  • outer 함수는 종료됐지만, outer 함수 내부 변수인 message는 inner함수를 통해 접근 가능하다. 여기서의 inner함수가 바로 클로저이다.

  • 이는 클로저의 특성으로 inner함수가 선언될 때 그 주변의 lexical environment(어휘적 환경) 즉, outer 함수의 lexical environment와 함께 묶였기 때문이다. 따라서 message라는 변수를 사용할 수 있게 된다.

0개의 댓글