본문 바로가기

JavaScript

클로져 (Closure)

반응형

 

 

클로져는 함수와 함수에 의해 생성되는 scope 객체를 함께 지칭하는 용어입니다. - MDN 'JavaScript 재입문하기 (JS 튜토리얼)

 

클로져는 JavaScript를 공부한다면 한 번쯤 골머리를 썩게 하는 알 듯 말듯한(?) 개념이다. scope와 closure 개념을 이론적으로 이해가 되었더라도 막상 코드를 작성하다 보면 이해가 가지 않는 상황이 와 버린다.. (모든 개발 언어가 그렇겠지만 항상 새롭다..^^)

 

최근 여러 강의들을 들으면서 접한 클로저에 대한 내용을 복기하고자 포스팅을 적어본다.

 

function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?

 

위 내용은 어떻게 수행되는 것일까?

makeAdder 함수 내에서 a와 b를 더하는 익명 함수를 호출한다.

add5, add20 변수에 각각 매개변수를 담은 익명 함수를 담고 실행시키면 그 익명 함수의 결과를 반환한다.

 

따라서 add5(6) =. 1, add20(7) = 27이다.

 

위와 같은 방식으로 외부 함수를 접근하게 되면 그것에 들어있는 변수들은 사라지지 않는다!

클로져의 부작용은 쉽게 메모리 누수가 된다는 점이다.

 

게다가, makeAdder 지역 변수의 서로 다른 두 "복사본"이 존재한다. JavaScript의 가비지 컬렉터는 리턴된 함수가 여전히 범위 객체를 참조하고 있으므로 결과적으로 makeAdder에 의해 리턴된 함수 객체가 더는 참조되지 않을 때까지 가비지 컬렉터에 의해 정리되지 않는다.

 

1. 함수가 실행될 때마다 새로운 scope 객체가 생성된다.

2. (브라우저에서 window로 접근가능한) global 객체와 달리 scope 객체는 JavaScript 코드에서 직접적으로 접근할 수 없다.

 

따라서, 우리는 브라우저의 성능 이슈를 방지하기 위해 메모리 누수를 막아야 한다.

메모리 누수를 막는 방법을 다양하겠지만 간단하게는 두 가지 방법으로 위 문제를 해결할 수 있다.

 

✔️해당 scope 객체를 할당하고 나면 필수적으로 obj= null 처리를 해 준다.

✔️ 또 다른 클로져를 추가한다.

이 방법은 클로져가 끝나고 나면 내부 함는 바로 사라진다.

이는 가비지컬렉터가 자동적으로 삭제해주므로 메모리 누수를 방지한다.

반응형