자바스크립트의 모든 함수는 클로저를 정의합니다.
클로저는 자바스크립트가 스킴(Scheme)에서 영향을 받아 받아들인 기능입니다.
여기서는 클로저의 개념을 가벼운 예시를 통해 알아보도록 하겠습니다.
클로저를 사용하면 데이터와 데이터를 조작하는 함수를 하나로 묶는 것이 가능해집니다.
객체지향 프로그래밍에서 프로퍼티를 조작하는 메서드와 같이 비슷한 맥락에 있다는 것인데요.
클로저의 어원은 '열려 있던 것을 닫는다'로서 먼저 변수의 유효 범위에 대해 알아봐야 합니다.
다음 코드를 보도록 하죠.
function first(){
var message = "Hello World";
function second(){
alert(message);
}
second();
}
first();
결과 :
second() 함수에는 message라는 변수가 선언되어 있지 않음에도, first() 함수에 선언해 놓은 변수에 접근하여 처리하는 것을 볼 수 있습니다.
이를 'lexical scoping', 즉 '어휘적 범위 지정' 이라고 하는데요.
하나의 예시를 더 보겠습니다.
function count(){
var cnt = 0;
return func;
function func(){
return cnt++;
}
}
var execute = count();
console.log(execute());
console.log(execute());
console.log(execute());
count()함수를 execute에 할당하여 3회 실행하면 다음과 같은 결과를 볼 수 있습니다.
처음의 예시와 마찬가지로, func() 함수는 count() 함수의 변수(여기서는 cnt)에 접근하여 처리하는 것을 볼 수 있네요.
클로저는 이와 더불어
"외부함수가 실행(리턴) 된 후에도 내부의 함수는 여전히 외부 함수의 변수에 접근하고 있다."
라는 중요한 특징을 가지고 있는데요.
예시를 조금만 바꿔보죠.
function count(){
var cnt = 0;
return {
func: function() {
return cnt++;
},
setCount: function(newNumber) {
cnt = newNumber;
}
}
}
var execute = count();
console.log(execute.func());
console.log(execute.func());
console.log(execute.func());
execute.setCount(10); //count값 변경
console.log(execute.func());
console.log(execute.func());
console.log(execute.func());
전의 예시와 마찬가지로, count() 함수를 execute에 할당하여 3회 실행해 보겠습니다.
그 후 변수 count의 값을 변경 후 다시 3회 실행해 보도록 하죠.
값이 변한 것을 확인 할 수 있습니다.
var execute = count();
이 시점에서 이미 외부함수 즉 count()는 실행(리턴)이 되었음에도, 내부의 함수가 count()의 변수에 접근하고 있어, 내부 함수에서 값을 변경해주자 그것이 적용된 것이죠.
이걸 이용하면 Java의 캡슐화, 그중에서도 은닉성을 흉내 낼 수 있습니다. 마치 Java에서 private으로 선언된 변수에 getter/setter와 같은 메서드로 접근하는 것 처럼 말이죠.
클로저는 이와 같이 내부 함수가 외부 함수에 접근할 수 있는 것을 가리킵니다.
클로저는 자바스크립트를 이용한 고난도의 테크닉을 구사하는데 필수적인 개념으로 활용되는데요.
다만 불필요한 상황에서 구현할 경우 성능에 부정적인 영향을 미칠 수 있으니 주의하시기 바랍니다.
참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
댓글 영역