1. 클로저의 개념

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  innerFunc();
}

outerFunc(); // 10

innerFunc함수는 자신이 속한 렉시컬 스코프를 참조할 수 있다.

즉, ①글로벌스코프 ②outerFunc 함수스코프 ③자신의 스코프를 참조할 수 있다.

 

★실행 컨텍스트 관점에서 설명

innerFunc이 호출되면 자신의 실행 컨텍스트가 콜스택에 쌓이고 변수 객체, 스코프체인, this에 바인딩할 객체가 결정된다.

스코프체인은 전역객체, outerFunc의 활성객체, 자신의 스코프를 가리키는 활성객체를 순차적으로 바인딩.

이것들이 바로 렉시컬 스코프의 실체라고 할수있다.

 

외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라 함.

 

MDN의 정리를 보면 클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경의 조합이다.

함수 == 반환된 내부함수

렉시컬 환경 == 내부함수가 선언됐을 때의 스코프 {...}

 

간단히 정리해, 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수라고 할 수 있다.

 

★다시 실행 컨텍스트 관점에서 설명

외부함수가 종료되어 실행 컨텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성객체(변수, 함수 등 정보가지고 있음)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프 체인을 통해 참조가능함.

 

 

2. 클로저 활용 (필요한 이유)

주로 비동기 작업, private 변수, 모듈 패턴 등 다양한 상황에서 활용될 수 있다.

e.g. 카운터 예제

  • 상태유지 : 현재상태를 기억하고 변경된 최신상태를 유지하는 상황에서 유용
  • 전역변수 사용억제 : 예상치 못한 side Effect를 일으킬 수 있기 때문에 최대한 전역변수를 줄이는 것이 좋다. 전역변수가 필요한 순간에 클로저를 활용할 수 있다.
  • 정보은닉 : 데이터를 보호할수 있다. 어떻게? 클래스 기반 언어의 private 흉내내서.

cf. 접근제어자 private (스터디에서 다룬 내용이 기억났다.)

자바스크립트는 프로토타입 기반 스크립트 언어로 접근제어자 기능이 없다.

무슨 뜻이냐면 변수에 접근제어자(private, public, protected)를 직접 부여하도록 설계되어 있지 않다.

하지만 클로저의 특성을 이용하면 이 접근 제어 기능을 흉내 낼 수 있다.

의미적으로 클래스 기반 언어의 private, public 구분 가능

 

+ Recent posts