Closure
함수와 함수가 선언된 어휘적(lexical) 환경의 조합
어휘적 환경(Lexical Environmnet)?
실행할 스코프 범위 안에 있는 변수와 함수를 프로퍼티로 저장하는 객체
소스코드를 실행하면서 참조가 필요한 변수의 값을 해당 Lexical Environment라는 객체에서 식별자 이름을 키로 찾는다
로컬 변수들을 프로퍼티로 갖는 객체인 환경 레코드(Environment Record)와 외부 어휘적 환경(Global Lexical Environment)에 대한 참조로 구성
Closure 관련 예제
function outer() {
const x = 10;
function inner() {
console.log(x);
}
return inner;
}
const example = outer();
example(); // 10
1. outer라는 함수의 호출이 시작될 때 새로운 렉시컬 환경이 만들어진다
outer 함수 실행에 필요한 변수를 해당 렉시컬 환경에 저장 => 해당 예시에서는 x 라는 로컬 변수 저장
2. inner라는 함수가 리턴되어 example 변수에 저장 (inner함수는 만들어지기만 했을 뿐 실행되지는 않음)
모든 함수는 [[Environment]]라는 내부 프로퍼티가 존재
해당 프로퍼티는 함수가 만들어 질 때 함수를 둘러싼 외부 렉시컬 환경에 대한 참조를 저장
3. inner함수가 만들어지면서 inner.[[Environment]] 프로퍼티에 outer함수의 렉시컬 환경에 대한 참조를 저장
4. 이후 inner함수가 호출 될 때 해당 함수의 렉시컬 환경 객체가 생성되고, 해당 객체가 외부 렉시컬 환경에 대한 참조를 inner.[[Environmnet]]에서 가져와서 outer 함수에서 변수를 참조
=> closure의 정의
정리하자면 클로저는 외부 변수를 기억하고 접근할 수 있는 함수
사실 자바스크립트에서는 모든 함수가 클로저
이미 생명주기가 종료된 outer 함수의 지역 변수를 어떻게 참조하는거지?
Garbage Collection
가비지 컬렉터는 변수 또는 데이터가 더 이상 사용되지 않을 때 자동으로 버려주는 역할을 수행
=> 도달 가능한 값은 메모리에서 삭제하지 않는다
=> 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수는 도달 가능한 값이다
A. 콜스택에서 어떤 함수의 실행 컨텍스트가 제거되었다고 해서 반드시 그 함수의 실행 컨텍스트의 렉시컬 환경까지 소멸하는 것은 아님
해당 outer 함수의 렉시컬 환경은 inner 함수의 내부 프로퍼티에 의해 참조되고 inner 함수는 전역 변수 example에 의해 참조되고 있기 때문에 가비지 콜렉션의 대상에서 벗어남
클로저 함수 장점
데이터 보존 가능
클로저 함수는 외부 함수의 실행이 끝나더라도 외부 함수 내 변수를 사용 가능
특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있다
정보의 접근 제한 (캡슐화)
'클로저 모듈 패턴'을 사용해 객체에 담아 여러개의 함수를 리턴하도록 해서 정보의 접근 제한이 가능
모듈화에 유리
클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용하고 보존이 가능
이와 같이 함수의 재사용성 극대화를 위해 함수 하나를 독립적인 형태로 분리하는 것을 모듈화라고 하는데 클로저를 통해 데이터와 메소드를 묶을 수 있어 클로저는 모듈화에 유리
사용 시 주의할 점
일반 함수를 사용했더라면 가비지 컬렉션 대상이 되었을 객체가 클로저 패턴에서는 메모리 상에 남아있는다
=> 가비지 컬렉션의 대상이 아니니까
따라서 클로저를 남발하게 되면 퍼포먼스 저하가 발생
property 자바스크립트에서 객체 내부의 속성
'FE Study' 카테고리의 다른 글
| [FE] JavaScript에서의 Class (0) | 2024.08.16 |
|---|---|
| [FE] JavaScript에서의 프로토타입(Prototype) (0) | 2024.08.09 |
| [FE] JavaScript에서의 this (0) | 2024.08.09 |
| [FE] JavaScript 동작원리 (1) | 2024.08.09 |
| [FE] Debounce와 Throttle (0) | 2024.08.02 |