클로저란?
클로저는 부모 함수가 종료된 후에도 부모의 스코프에 접근할 수 있는 환경 또는 함수입니다.
클로저가 어떻게 만들어지고 동작하는지 예제를 따라가보도록 하겠습니다.
함수 선언
아래의 자바스크립트를 실행하면 그림처럼 window 객체에 대한 환경이 생성됩니다.
(메모리 어딘가에 생성되었을 객체와 관련된 일련의 것들을 '환경'이라고 표현하겠습니다.)
var g = 0;
function outter() {
var a = 0;
return function innner() {
g++;
a++;
console.log(g + ', ' + a);
}
}
① 자바스크립트에는 기본적으로 window라는 객체가 존재하며, 전역객체라고 불리기도 합니다.
② 객체 안에 g라는 전역변수가 생성되었습니다.
③ 객체 안에 outter라는 함수가 생성되었습니다.
※ outter 함수는 아직 실행되지 않았습니다.
outter 함수 실행
outter 함수를 실행시켜보도록 하겠습니다.
var g = 0;
function outter() {
var a = 0;
return function innner() {
g++;
a++;
console.log(g + ', ' + a);
}
}
var func1 = outter();
① outter 함수를 실행시키면 outter 환경이 생성됩니다.
② outter 함수가 종료되면 function inner() {...} 가 func1 변수로 반환됩니다.
※ func1은 outter 환경 내의 inner 함수 객체를 가리키게 됩니다. func1을 실행하면 inner 함수가 outter 환경 내에서 실행됩니다.
※ outter 함수가 종료되더라도 outter 환경은 사라지지 않습니다. 이것이 클로져의 핵심입니다.
※ inner 함수는 아직 실행되지 않았습니다.
반환된 inner 함수를 실행시켜보도록 하겠습니다.
var g = 0;
function outter() {
var a = 0;
return function innner() {
g++;
a++;
console.log(g + ', ' + a);
}
}
var func1 = outter();
func1();
func1();
① func1이 가리키는 inner 함수는 outter 환경 내에서 실행됩니다.
② outter 환경의 a를 1 증가시킵니다.
→ inner 함수 내에서 a를 찾을 수 없으므로 상위의 outter 환경 내에서 찾습니다.
③ window 환경의 g를 1 증가시킵니다.
→ inner 함수 내에서 g를 찾을 수 없으므로 상위의 outter 환경 내에서 찾습니다.
→ outter 환경 내에서도 g를 찾을 수 없으므로 상위의 window 환경 내에서 찾습니다.
func1 함수를 반복하여 실행한 결과는 아래와 같습니다.
1, 1 //func1();
2, 2 //func1();
반복
outter 함수를 실행하고, 반환된 inner 함수를 한번 더 실행시켜보겠습니다.
var g = 0;
function outter() {
var a = 0;
return function innner() {
g++;
a++;
console.log(g + ', ' + a);
}
}
var func1 = outter();
func1();
func1();
var func2 = outter();
func2();
func2();
① outter 함수가 실행되면 새로운 outter 환경이 생성됩니다.
② outter 함수가 종료되면 function inner() {...} 함수가 func2 변수로 반환됩니다.
③ func2가 가리키는 inner 함수는 새로운 outter 환경 내에서 실행됩니다.
④ 새로운 outter 환경의 a를 1 증가시킵니다.
⑤ window 환경의 g를 1 증가시킵니다.
func1, func2 함수를 반복하여 실행한 결과는 아래와 같습니다.
1,1 //func1();
2,2 //func1();
3,1 //func2();
4,2 //func2();
결론
1. 외부함수를 실행할 때마다 새로운 환경(지역변수 + 내부함수)이 생성된다.
2. 외부함수가 종료되어도 환경은 사라지지 않는다.
3. 내부함수는 자신이 생성된 환경 내에서 실행되기 때문에 환경 내의 지역변수에 접근할 수 있다.
응용
이러한 클로저를 활용하면 클래스와 유사한 형태로 코드를 모듈화할 수 있습니다.
var class = function() {
/* private */
var privateVar = 'private';
/* public */
var publicVar = 'public';
var publicFunc = function() {
console.log(privateVar);
};
return {
variable: publicVar,
func: publicFunc
};
};
/**
* class 함수를 실행하면 class 환경이 생성되고 { variable: ..., func: ... }가 반환된다.
*/
/**
* variable을 통해 class 환경 내의 publicVar 변수를 참조할 수 있다.
*/
console.log(myclass.variable); // "public" 출력
/**
* func을 통해 class 환경 내의 publicFunc 함수를 실행할 수 있다.
* publicFunc 함수는 class 환경의 privateVar 변수를 참조하여 출력합니다
*/
myclass.func(); // 'private' 출력
/**
* privateVar에는 접근할 수 있는 방법이 없다.
*/
'Javascript' 카테고리의 다른 글
비밀번호 규칙 정규식 (0) | 2019.11.18 |
---|---|
[javascript] 문자열 n번째 자리에 문자 삽입하기 (0) | 2018.06.21 |