학습 목표
- 클로저 함수의 정의와 특징에 대해서 이해할 수 있다.
- 클로저가 갖는 스코프 범위를 이해할 수 있다.
- MDN은 클로저를 아래와 같이 정의한다.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). - mdn (2023)
아래의 코드에서 클로저를 찾아보자 ! 🙋♀️
const globalVar = '전역 변수';
function outerFn() {
const outerFnVar = 'outer 함수 내의 변수';
const innerFn = function() {
return 'innerFn은 ' + outerFnVar + '와 ' + globalVar + '에 접근할 수 있습니다.';
}
return innerFn;
}
위 코드에 있는 함수부터 찬찬히 살펴보자.
outerFn
에서는 변수 globalVar
에 접근할 수 있다.innerFn
에서는 변수 globalVar
와 함수 outerFn
내부의 outerFnVar
에 접근할 수 있다.즉, 위 코드에서 클로저는 두 조합을 찾을 수 있다.
outerFn
과 outerFn
에서 접근할 수 있는 변수 globalVar
innerFn
과 innerFn
에서 접근할 수 있는 변수 globalVar
, outerFnVar
변수의 접근 범위인 스코프와 비슷한 개념인데, 왜 따로 클로저만 구분을 할까?
클로저의 함수는 어디에서 호출되느냐와 무관하게 선언된 함수 주변 환경에 따라 접근할 수 있는 변수가 정해지기 때문이다.
또 변수를 안전하게 보호하기 위해 많이 사용한다. 아래 예시와 함께 살펴보자.
- 여기 클로저가 아닌 함수가 있다.
- 함수를 실행할 때마다 값이 1씩 증가하는 것을 볼 수 있다.
(잘 작동 되는데 이러면 안써도 되지 않나? 🤷♀️ -> 않다. 왜냐하면..)
- 실수로 같은 변수의 이름(
num
)에 다른 값을 줄 수 있기 때문이다.
- 그렇게 되면 변수
num
이 영향을 받아 오염 될 수 있다.
- 그럼
num
을 지역 변수로 넣으면 되지 않을까?
- 이크! 계속 같은 값인 1이 나오게 된다.
함수를 호출할 때마다 변수num
이 0으로 초기화 되기 때문이다.
- 이러한 이유로 사용되는 것이 바로 클로저이다.
- 이렇게 클로저를 사용하면 외부에서
num
이라는 변수를 사용하지 못하므로 변수가 안전하게 보호 되면서,(이것을 은닉되어 있다고 한다.)- 또 다른 변수에
increase
함수의 호출값(리턴되고 있는 함수)를 할당하고
그 변수는increase
함수가 리턴하고 있는 함수와 동일하게 작동한다.