클로저
# 클로저(Closure)란
클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여, 만일 자신이 선언됐을 때의 스코프 밖에서 호출되어도 스코프에 접근할 수 있는 함수를 말한다. 클로저는 자바스크립트 고유의 개념이 아니라 함수형 프로그래밍 언어에 등장하는 보편적인 특성이다. 객체지향 프로그래밍과 함수형 프로그래밍을 모두 아우르는 개념이기에 매우 중요하다. 예시를 통해 알아보자.
function outer() {
const x = 10;
const inner = function () {
console.log(x);
};
return inner;
}
const result = outer();
result(); // 10
함수 outer는 내부함수 inner를 반환하고 난 뒤 콜스택에서 사라진다. outer의 실행 컨텍스트가 사라졌으므로 outer에 있는 변수 x 또한 더 이상 존재하지 않게 된다. 따라서 const result = outer(); 코드 이후에는 변수 x를 참조할 수 없을 것처럼 보인다. 하지만 위 코드를 실행해보면 10이라는 값이 반환된다. 즉, x라는 변수가 사라지지 않고 여전히 참조 가능한 값으로 존재하고 있는 것이다.
이처럼 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있다. 즉, 함수A에서 선언한 변수 a를 내부함수B가 사용할 경우, 함수A의 실행 컨텍스트가 종료된 이후에도 변수 a는 사라지지 않고 접근할 수 있다. 이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수. 이러한 함수를 클로저라고 한다.
# 클로저의 용도
클로저는 상태를 안전하게 변경하고 유지하기 위해 사용한다. 상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고, 특정 함수에게만 상태 변경을 허용하기 위해 사용한다. 또한, 전역 변수 사용을 억제할 수 있다.
function closure() {
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
function cntPrint() {
console.log(cnt);
}
return {
cntPlus,
cntPrint,
};
}
const cntClosure = closure();
cntClosure.cntPlus();
cntClosure.cntPrint();
변수 cnt는 클로저에 의해 참조되고 있기 때문에 자신의 변경된 최신 상태를 계속해서 유지할 수 있다. 또한, 클로저를 이용하면 전역 변수를 사용하지 않고도 상태를 관리할 수 있고 클로저 함수 내에서 선언된 변수 cnt는 외부에서 접근할 수 없다. 따라서 특정 함수에게만 상태 변경 허용됨으로써 예기치 않게 값이 건드려지는 상황을 미리 방지할 수 있다.
리액트의 useState가 생각난다 원리가 비슷해보임😮
참고 자료
책 '모던 자바스크립트 Deep Dive' 24장
책 '코어 자바스크립트' 5장
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%ED%81%B4%EB%A1%9C%EC%A0%80
'FE > JavaScript' 카테고리의 다른 글
[JavaScript] 프로퍼티 어트리뷰트 (0) | 2023.03.31 |
---|---|
[JavaScript] this (0) | 2023.03.26 |
[JavaScript] 프로토타입 (0) | 2023.03.17 |
[JavaScript] 객체지향과 Class 함수 (0) | 2023.03.14 |
[JavaScript] 자주 사용하는 자바스크립트 코드 정리 (1) | 2023.03.07 |