Javascript

Javascript 클로저 이해하기

behonestar 2015. 5. 17. 13:07

클로저란?
클로저는 부모 함수가 종료된 후에도 부모의 스코프에 접근할 수 있는 환경 또는 함수입니다.

클로저가 어떻게 만들어지고 동작하는지 예제를 따라가보도록 하겠습니다.


함수 선언

아래의 자바스크립트를 실행하면 그림처럼 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 함수 실행

반환된 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:  ... }가 반환된다.

 */

var myclass = class();

/**

 * 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