자바스크립트를 공부하다보면 클로저(Closure)
에 대해 이야기하는 것을 많이 볼 수 있었다. 그렇다면 이 클로저는 무엇이고 어떻게 쓰이는 것인가에 대해 알아보았다.
클로저
는 함수 내부에서 생성한 데이터와 그 유효범위로 인해 발생하는 특수한 현상 / 상태이다. MDN에서는 아래와 같이 정의하고있다.
“A closure is the combination of a function and the lexical environment within which that function was declared.”
클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.
하지만 저 글을 읽었을 때 이해가 되지 않아서 예시들을 찾아봤고, 클로저
에 대해 정의를 내렸다.
클로저는 자신을 포함하고 있는 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라고 부른다.
아직도 이해가 잘 안될 수 있으니 코드를 보며 더 자세히 알아보자.
function outerFunc() {
var x = 10;
var innerFunc = function () { console.log(x); };
return innerFunc;
}
/**
* 함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
* 그리고 함수 outerFunc의 실행 컨텍스트(var x = 10, var innerFunx)는 소멸한다.
*/
var inner = outerFunc();
inner(); // 10
외부 함수 outerFunc
이 있고, 내부 함수 innerFunc
가 있다. outerFunc
이 실행이 되고 변수 x
에 10의 값을 넣고 innerFunc
를 호출하고 outerFunc
은 생을 마감했다. 변수 x
또한 outerFunc
과 같이 생을 마감했기 때문에 유효하지 않게 되었다.
그래서 내부함수innerFunc
에서 x
를 출력하면 아무것도 나오지 않을 것 같지만 10이 출력된다.
이처럼 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수이다.
또한, 클로저는 자신을 포함하고 있는 외부 함수의 인자
, 지역변수
등을 외부 함수가 종료된 후에도 사용할 수 있다. 이러한 변수를 자유 변수(free variable)
라고 부르고, x
가 이에 해당한다.
다른 표현으로는 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수
라고 할 수 있다.
위에서 클로저에 대해 알아보았고, 클로저를 사용함으로써 얻을 수 있는 이점에 대해 간단한 예제를 통해 알아보겠다.
- 접근 권한 제어
- 지역변수 보호
- 데이터 보존 및 활용
function a() {
var x = 1;
function b() {
console.log(x);
}
b();
}
a();
console.log(x); // ReferenceError: x is not defined
x = 2; // ReferenceError: x is not defined
여기서 맨 아래의 x는 에러가 난다. 접근할 수가 없어서 인식을 못하기 때문인데 접근 권한 제어
의 이점을 받고 있다. 그리고 지역변수를 함수 밖에서 바꾸려고하면 또 에러가 난다. 이 말은 곧, 함수 a에 선언된 지역변수 x를 보호
해준다는 것이다.
그래서 클로저가 가장 유용하게 사용되는 상황은 현재 상태를 기억하고 변경된 최신 상태를 유지해야하는 상황이다.