Frontend/JavaScript
[JavaScript] 코어 자바스크립트 5장 - 클로저
반응형
아래 책을 읽고 정리한 내용입니다.
http://www.yes24.com/Product/Goods/78586788
💡A closure is the combination of a function and the lexical environment within which that function was declared.
클로저란?
클로저는 여러 함수형 프로그래밍 언어에서 등장하는 보편적인 특성이다. MDN에 따르면, 클로저란 함수와 그 함수가 선언될 당시의 lexical environment
의 상호관계에 따른 현상이다. 여기서 선언될 당시의 lexical environment
란 실행 컨텍스트의 구성 요소 중 하나인 outerEnvironmentReference
에 해당하며, 상호관계란 내부 함수에서 외부 변수를 참조하는 경우를 말한다.
즉, 클로저란 "어떤 함수에서 선언한 변수를 참조하는 내부함수에서 발생하는 현상"으로 볼 수 있다.
대표적인 클로저 예시를 통해 자세히 살펴보자.
- outer는 inner함수 자체를 반환하는 함수이다.
- outer 함수의 실행 컨텍스트가 종료될 때, outer2 변수는 inner함수를 참조하게 된다.
- 따라서 outer2를 통해 outer의 실행 컨텍스트가 종료된 후에도 inner함수를 호출할 수 있다.
var outer = function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
};
var outer2 = outer(); //outer 종료, outer2는 inner 참조
console.log(outer2()); //2
console.log(outer2()); //3
inner 실행(outer2 호출) 시점에 outer는 이미 실행이 종료된 상태인데 어떻게 a에 접근할 수 있는 것일까?
- 이는 가비지 컬렉터의 동작 방식 때문이다. 가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집 대상에 포함시키지 않는다.
- outer의 실행이 종료되더라도 내부 함수인 inner를 참조하는 변수 outer2가 있기 때문에 outer는 가비지 컬렉터의 수집 대상에서 제외되는 것이다.
- outer2에 의해 inner 함수의 실행 컨텍스트가 활성화되면
outerEnvironmentReference
가 outer함수의LexicalEnviornment
를 필요로 할 것이기 때문이다.
따라서 inner함수가 a에 접근할 수 있는 것이다.
그래서 클로저란?
- 어떤 함수에서 선언한 변수를 참조하는 내부함수에서만 발생하는 현상
- 외부 함수의
LexicalEnvironment
가 가비지 컬렉팅되지 않는 현상 - 어떤 함수 outer에서 선언한 변수 a를 참조하는 내부 함수 inner를 외부로 전달할 경우, outer의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상. 그래서 접근할 수 있는 현상.
클로저와 메모리 관리
클로저는 GC의 수거 대상이 되지 않는 현상을 말하기 때문에, 메모리 누수에 대한 문제가 있다. 따라서 클로저의 필요성이 사라진 시점에는 더 이상 메모리를 소모하지 않도록 해주어야 한다. How? 참조 카운트를 0으로 만들면 된다.
참조 카운트를 0으로 만드는 방법은?
- 식별자에 참조형이 아닌 기본형 데이터를 할당하면 된다.
- 일반적으로
null
이나undefined
를 할당한다.
var outer = (function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
})();
console.log(outer); //[Function: inner]
outer = null;
console.log(outer); //null
클로저 활용 사례
- 콜백 함수 내부에서 외부 데이터를 사용하고자 할 때
- 접근 권한 제어(정보 은닉)
- 클로저를 이용하면 함수 차원에서 public 한 값과 privat 한 값을 구분하는 것이 가능하다.
- 외부 스코프에서 함수 내부의 변수들 중 선택적으로 일부 변수에 대한 접근 권한을 부여할 수 있다.
- 외부에 제공하고자 하는 정보를 모아서 return 하고, 내부에서만 사용할 정보들은 return 하지 않는 것으로 접근 권한 제어가 가능한 것이다.
- 부분 적용 함수
- 부분 적용 함수란 n개의 인자를 받는 함수에 미리 m개의 인자만 넘기고, 나중에 (n-m) 개의 인자를 넘겨 함수 실행 결과를 얻을 수 있는 함수이다.
- 미리 일부 인자를 넘겨두어 기억하게끔 하고 추후 필요한 시점에 기억했던 인자들까지 함께 실행하게 하는 것이 클로저의 정의에 부합하다.
- ex) 디바운스: 짧은 시간 동안 동일한 이벤트가 많이 발생할 경우 이를 전부 처리하지 않고 처음 또는 마지막에 발생한 이벤트에 대해 한 번만 처리하는 것
- 커링 함수
- 커링 함수는 여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인 형태로 구성한 것을 말한다.
- 당장 필요한 정보만 받아서 전달하고 또 필요한 정보가 들어오면 전달하는 식으로, 마지막 인자가 넘어갈 때까지 함수 실행을 미루는 "지연 실행"을 수행한다.
각 사례의 구체적 예시는 책을 참고하자.
반응형
'Frontend > JavaScript' 카테고리의 다른 글
[JavaScript] 코어 자바스크립트 7장 - 클래스 (0) | 2023.06.08 |
---|---|
[JavaScript] 코어 자바스크립트 6장 - 프로토타입 (0) | 2023.06.07 |
[JavaScript] 코어 자바스크립트 4장 - 콜백 함수 (0) | 2023.05.29 |
[JavaScript] 코어 자바스크립트 3장 - this (0) | 2023.05.27 |
[JavaScript] 코어 자바스크립트 2장 - 실행 컨텍스트 (feat. 호이스팅, 스코프 체인) (0) | 2023.05.25 |