5-1 클로저의 의미 및 원리 이해
- 클로저는 여러 함수형 프로그래밍 언어에서 등장하는 보편적인 특성이다.
- JS 고유의 개념이 아니기 때문에 다양한 문헌에서 제각각 클로저를 다르게 정의 또는 설명하고 있다.
- 다양한 책에서 클로저를 한문장으로 설명하는 부분들
- 자신을 내포하는 함수의 컨테스트에 접근할 수 있는 함수 - <자바스크립트 핵심 가이드>
- 함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 것 - <러닝 자바스크립트>
- 함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 있는 함수 - <자바스크립트 닌자 비급>
- 이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 함수 - <인사이드 자바스크립트>
- 자유변수가 있는 함수와 자유변수를 알 수 있는 환경의 결합 - <Head First Javascript Programming>
- 로컬 변수를 참조하고 있는 함수 내의 함수 - < 자바스크립트 마스터북>
- 자신이 생성될 때의 스코프에서 알 수 있었던 변수들 중 언젠가 자신이 실행될 때 사용할 변수들만을 기억하여 유지시키는 함수 - 함수형 자바스크립트 프로그래밍
- MDN에서 클로저에 대해 소개하고 있는 문장을 변역해보자면
- 클로저는 함수와 그 함수가 선언될 당시의 Lexical environment의 조합.
- 선언될 당시의 Lexical environment === outerEnvironmentReference
- 어떤 컨텍스트 A에서 선언한 내부함수 B의 실행 컨텍스트가 활성화된 시점에는 B의 outerEnvironmentReference가 참조하는 대상인 A의 LexicalEnvironment 에도 접근가능.
- A는 B에서 선언한 변수에 접근할 수 없지만 B는 A에서 선언한 변수에 접근할 수 있다.
- 내부함수 B가 A의 LexicalEnvironment를 언제나 사용하는 것은 X
- 내부함수에서 외부 변수를 참조하는 경우에 한해서만!
- 클로저: 어떤 함수에서 선언한 변수를 참조하는 내부함수에서만 발생하는 현상
- 즉, 외부 함수의 LexicalEnvironment 가 가비지 컬렉팅 되지 않는 현상
- inner함수 실행 시점에 outer함수가 이미 실행이 종료된 상태인데 outer 함수의 LexicalEnvironment에 어떻게 접근할 수 있는 것일까?
- 가비지 컬렉터의 동작 방식 때문
- 가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집 대상에 포함시키지 X
- 함수의 실행 컨텍스트가 종료된 후에도 LexicalEnvironment가 가비지 컬렉터의 수집 대상에서 제외되는 유일한 경우는 지역변수를 참조하는 내부함수가 외부로 전달된 경우이다.
- 가비지 컬렉터의 동작 방식 때문
→ 클로저란 어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상
- 외부로 전달이 곧 return만을 의미하는 것은 아니다.
- 콜백으로 전달하는 경우도 포함
5-2 클로저와 메모리 관리
- 메모리 소모는 클로저의 본질적인 특성이다.
- 개발자가 의도적으로 참조 카운트 0이 되지 않게 설계한 경우는 ‘누수’라고 할 수 없다.
- 클로저는 의도적으로 함수의 지역변수를 메모리를 소모하도록 함으로써 발생한다.
- 필요성이 사라진 시점에서 참조카운트 0으로 만든다면 소모된 메모리가 회수된다.
- 식별자에 기본형데이터(null/undefined)를 할당.
5-3 클로저 활용 사례
5-3-1 콜백 함수 내부에서 외부 데이터를 사용하고자 할 때
5-3-2 접근 권한 제어(정보 은닉)
- 정보 은닉은 어떤 모듈의 내부 로직에 대해 외부로의 노출을 최소화해서 모듈간의 결합도를 낮추고 유연성을 높이고자 하는 현대 프로그래밍 언어의 중요한 개념 중 하나
- JS에서는 기본적으로 변수 자체에 접근 권한을 직접 부여하도록 설계돼 있지 않음.
- 클로저를 이용하면 함수 차원에서 public 값과 private값을 구분할 수 있다.
- 클로저를 활용하면 외부 스코프에서 함수 내부의 변수들 중 선택적으로 일부의 변수에 대한 접근 권한을 부여할 수 있다.
- outer함수는 외부(전역 스코프)로부터 철저하게 격리된 닫힌 공간
- 외부에서 outer함수를 실행할 수는 있지만 outer 함수 내부에는 어떠한 개입도 할 수 없다.
- return값이 외부에 정보를 제공하는 유일한 수단
- 접근제어 하는 방법
- 함수에서 지역변수 및 내부함수 등을 생성
- 외부에 접근권한을 주고자 하는 대상들로 구성된 참조형 데이터(대상이 여럿일 때는 객체 또는 배열, 하나일 때는 함수)를 return
5-3-3 부분 적용 함수
- 부분 적용 함수: n개의 인자를 받는 함수에 미리 m개의 인자만 넘겨 기억시켰다가, 나중에 (n-m)개의 인자를 넘기면 비로소 원래 함수의 실행결과를 얻을 수 있게 하는 함수
- 디바운스: 짧은 시간 동안 동일한 이벤트가 많이 발생할 경우 이를 전부 처리하지 않고 처음 또는 마지막에 발생한 이벤트에 대해 한번만 처리하는 것
5-3-4 커링 함수
- 커링 함수: 여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 나눠서 순차적으로 호출될 수 있게 체인 형태로 구성한 것
- 커링은 한 번에 하나의 인자만 전달하는 것을 원칙
- 중간 과정상의 함수를 실행한 결과는 그 다음 인자를 받기 위해 대기만 할 뿐.
- 마지막 인자가 전달되기 전까지는 원본 함수가 실행되지 않음
- 원하는 시점 까지 지연 시켰다가 실행하는 것이 요긴할 때 적합하다.
디바운스→ 무한스크롤 + 더보기 버튼 연타 방지