Home 클로저 Closure
Post
X

클로저 Closure

Javascript에서의 클로저를 알아보자.


Closure 클로저

Closure는 폐쇄 의 의미로 쓰입니다.
Javascript의 클로저도 비슷한 의미를 갖습니다.

함수가 선언될 당시 주변 환경과 함께 갇힌다는 의미입니다.

클로저는 함수함수가 선언된 어휘적 환경(Lexical Scope)의 조합입니다.

깊게 말하면, 함수가 속한 렉시컬 환경(Lexical Environment)을 기억하고, 함수가 렉시컬 환경 밖에서 실행될 때도 해당 스코프(Scope)에 접근할 수 있는 것을 말합니다.


예제

1
2
3
4
5
6
7
8
9
10
function makeClosureFunc(hi) {
  const name = "peter";
  return function () {
    console.log(`${hi} ${name}~!`);
  };
}

const sayHiToPeter = makeClosureFunc("Good morning!");

sayHiToPeter(); //Good morning! peter~!
  • makeClosureFunc : 익명 함수를 return 합니다.
  • return 함수 : makeClosureFunc의 scope에 있는 name과 hi 변수를 사용하고 있습니다.

CallStack에는 실행 컨택스트가 추가되고 삭제됩니다.

  • makeClosureFuncFunctional Execution Context가 추가된다
  • makeClosureFuncFunctional Execution Context가 삭제된다
  • sayHiToPeterFunctional Execution Context가 추가된다
  • sayHiToPeterFunctional Execution Context가 삭제된다

변수 sayHiToPeter는 외부 함수인 makeClosureFunc의 밖에 선언되어있습니다.

이 때, makeClosureFunc실행 종료되어 실행 컨택스트가 CallStack에서 삭제 되었어도, return된 함수는 makeClosureFunc의 lexical environment를 참조할 수 있습니다.

즉, 외부 함수의 실행이 끝난 후 소멸된 이후에 내부함수가 외부함수의 변수에 접근할 수 있는 것을 말합니다.


Closure의 구현 방식

위의 예제로 Closure의 구현 방식에 대해 알아보겠습니다.

실행 컨택스트는 함수가 실행되는 환경 정보를 갖고 있는 객체입니다.

함수가 실행 될 때 CallStack에 추가되며 실행이 종료되면 CallStack에서 종료됩니다.

하지만 CallStack에서 제거된다는 것이 메모리에서 삭제됨을 뜻하는 것은 아닙니다.

이전 포스트에서 자바스크립트는 가비지 컬렉터가 메모리 관리를 알아서 해준다고했습니다.

가비지 컬렉터가 사용하는 mark and sweep 알고리즘‘root에서 닿을 수 있는’ 객체들의 reachable을 true로 표시하고, false인 객체들은 메모리에서 해제시킵니다.

  • makeClosureFunc의 함수 실행이 종료되며 makeClosureFunc의 Execution Context가 CallStack에서 제거됩니다.
  • 가비지 컬렉터가 makeClosureFunc의 Lexical Environment를 메모리에서 지워도 될 지 reachable을 확인합니다.
  • 전역 변수인 sayHiToPeter가 Closure 함수를 참조하고 있고, Closure 함수의 Outer Reference가 makeClosureFunc의 Lexical Environment를 참조하고 있기 때문에 makeClosureFunc의 Lexical Environment는 root에서 닿을 수 있는 상태입니다.
  • makeClosureFunc의 Lexical Environment는 메모리에서 제거되지 않습니다.

즉, Closure 함수를 전역 객체가 참조하고 있기 때문에 Closure의 Outer Reference도 메모리에서 삭제되지 않고 계속 유지됩니다.


Closure의 장단점

Closure는 캡슐화를 구현하기에 매우 적합한 장치입니다.

Closure를 통해 살려놓은 변수는 외부에서는 조작할 수 없고 오로지 내부에서만 조작 가능하다는 특징이 있습니다.

이는 의도치않은 변경을 막아주고 의도한 변경만을 할 수 있는 환경을 가지게된다는 것을 뜻합니다.

자바스크립트에서는 객체지향 프로그래밍을 구현하는 키워드인 private, public등의 키워드가 존재하지 않지만 Closure를 통해 public과 private를 어느정도구현해낼 수 있습니다.

하지만, 가비지 컬렉터의 콜렉션 대상이 되지 않는 클로저는 불필요하게 사용하면 메모리 누수를 일으킬 수 있습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.