본문 바로가기

javascript/Learn

[javascript] 클로저(closure) 란?


명확하게 이해하고 있는 것은 아니지만, 이해하는 부분까지 써내려가 본다.

클로저.
본디 함수내의 지역변수는 그 함수가 끝나는 순간 지역변수는 사라진다.
그러나 자바스크립트에서는 함수중첩을 이용하여,
해당 함수가 끝나도 그 함수안의 지역변수가 유지되고,
외부에서 특정 함수의 지역변수에 직접전근을 가능하게 하는 것이 클로저 다.
함수호출이 종료되더라도 그 함수의 지역변수 및 지역변수 체인 관계를 유지할 수 있는 구조 이다.


클로저가 생성된 소스를 보자

        var x = "global"
function f()
{
var x = "local"
function g(){ alert(x); }
g();
}
f();

이 소스의 결과는 local이 보여진다.

함수 f에 정의되어 있는 지역 변수 x를 함수 g에서 접근했다.
이로인해 지역변수 x가 함수가 끝나도 여전히 메모리에 올라가 있는 상황이 된다.


좀 더 이해를 돕기 위해 위 함수를 보기 쉽게 풀어 써보면....

var x = "global"
function f()
{
var x = "local"
g();
}

function g()
alert(x); 
}

f();



이와 같다.
이코드도 똑같이 함수 f를  호출하면 그 안에서 함수 g를 다시 호출한다.
그러나 이 코드의 결과는 global이 보여진다. 

이 코드에선 함수 g가 함수f 의 지역 변수에 접근을 할 수 없다.


클로저 인스턴스

다른 객체지향 언어에서 클래스가 인스턴스화 되는 것 처럼 클로저를 이용하여 유사한 효과를 볼 수 있다.

다음 코드를 보자

function outer() {

var x=0;

return function () {

return ++x;

};

}

위의 outer 함수를 변수에 할당하는 것을, 클래스의 인스턴스화와 매우 유사하다.

var f = outer();  //outer f = new outer(); 와 같은 효과


그렇다면 다음의 코드는 어떻게 될까?

var f = outer();

f();

f();

var g = outer();

g();

g();

정답은 차례로 

1

2

1

2

가 된다.


해당 코드를 자바로 표현하면 다음과 같다고 생각하면 된다.

public class outer {

private int x;

public outer() {

x = 0;

}

public int getX() {

return ++x;

}

}


실행 코드

outer f = new outer();

System.out.println(f.getX());

System.out.println(f.getX());

outer g = new outer();

System.out.println(g.getX());

System.out.println(g.getX())