클로저(Closure)란?
MDN에서는 클로저를 이와 같이 정의합니다.
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.
클로저는 함수와 그 함수가 선언됐을 경우 렉시컬 환경(Lexical environment)과의 조합입니다.
정의만 읽어봤을 때는 무슨 뜻인지 잘 와닿지 않았습니다.
예제를 통해서 알아보겠습니다.
function outer(){
const name = 'ujam';
function inner(){
console.log(name);
}
return inner;
}
var getName = outer();
getName(); //ujam
outer 함수는 내부에 inner 함수 반환하고 종료합니다.
outer 함수는 실행한 후 콜 스택에서 제거되었으므로 outer 함수 내부에 있는 변수 name은 유효하지 않다고 예상 할 수 있습니다.
하지만 실행 결과는 변수 name의 값인 ujam이 나오게됩니다.
이미 outer 함수는 실행된 후에 종료되어 콜 스택에서 제거됐지만 지역변수 name은 값을 유지한 채 제대로 출력하고 있습니다.
위와 같이 외부함수보다 내부함수가 더 오래 유지되는 경우, 해당 외부함수 밖에서 내부함수가 호출할 때 외부함수의 지역 변수에 접근할 수 있습니다.
이러한 함수를 클로저라고 부릅니다.
클로저를 유용하게 사용할 수 있는 예시를 들어보고자 합니다.
const increase = () => {
let count = 0;
return ++count;
};
for (let i = 0; i < 5; i++) {
const result = increase();
console.log(result);
}
// 1
// 1
// 1
// 1
// 1
위 코드는 increase 함수는 지역변수 count를 0으로 세팅한 후 ++count를 리턴해줍니다.
for문을 통해 increase 함수를 반복해서 돌리게 되면 값은 밑의 주석과 같이 나오게 됩니다.
당연한 결과입니다.
반복문이 몇 번 돌던 관계없이 다시 함수를 호출할 때 지역변수인 count은 0으로 초기화 해주니 값은 일정하게 1로 나올 수 밖에 없습니다.
증감된 count 상태를 기억하고 상태를 유지할 수 있다면 count는 카운트로서 제대로 된 역할을 할 수 있을겁니다.
const increase = (function() {
let count = 0;
return function inner() {
return ++count;
}
}());
for (let i = 0; i < 5; i++) {
const result = increase();
console.log(result);
}
// 1
// 2
// 3
// 4
// 5
위 코드에 변수 increase에는 inner 함수가 할당됩니다.
inner 함수는 생성될 때의 렉시컬 환경을 기억하는 클로저입니다.
즉시실행함수는 호출된 이후 소멸됩니다.
하지만 즉시실행함수가 반환한 함수는 변수 increase에 할당되어서 inner 함수는 자신이 선언됐을 때의 렉시컬 환경인 즉시실행함수의 스코프에 속한 지역변수 count를 기억합니다.
즉 즉시실행함수의 변수 count에 접근할 수 있으며 변수 count는 자신을 참조하는 함수가 소멸될 때까지 상태를 유지합니다.
이렇듯 변수 count는 private 변수이기 때문에 전역 변수를 사용하게 된다면 의도되지 않은 값의 변경을 걱정하게 될텐데 그럴 필요가 적어지기 때문에 안정적인 프로그래밍이 가능합니다.
클로저를 사용하는 이유들은
1. 현재 상태를 기억하고 변경된 최신 상태에 유지가 필요할 경우
2. 전역 변수의 사용을 지양할 경우
3. 정보 은닉이 필요할 경우
이것이 우리가 클로저를 사용하는 이유입니다.
'Study > JavaScript' 카테고리의 다른 글
[Javascript] 프로미스(Promise)란? (0) | 2022.05.01 |
---|---|
[Javascript] 콜백(Callback)이란? (0) | 2022.04.22 |
[JavaScript] 스코프(Scope)란? (0) | 2022.04.09 |
[JavaScript] var, const, let 키워드 차이점 (0) | 2022.04.05 |
이벤트 루프(Event Loop)란? (0) | 2022.01.24 |