유효 범위와 관련해서 클로저(closure) 패턴에 대해 이해해보자.
클로저(closure)는 영어의 본 의미는 '폐쇄'라는 뜻을 가지고 있다. 폐쇄라는 것은 외부와의 연결을 끊겠다는 뜻이다.
클로저(closure)는 ECMAScript 관점에서 본다면 유효 범위(scope)에 대한 문법이라 할 수 있다. ECMAScript는 함수의 반환 값으로 다른 함수를 지정할 수 있다. 그리고 반환된 함수는 반환 시점에서의 환경을 그대로 기억하고 유지한다. 이것이 클로저(closure)의 핵심이다.
다음 코드는 클로저(closure)를 설명하는 일반적인 샘플 코드이다.
closureTest()
함수에서 반환하는 값은 함수이다. 반환되는 함수 내부에는 상위 스코프의 x
라는 변수를 사용하고 있다. 반환되는 함수 내부의 값은 반환되는 시점의 환경을 기억한다. 따라서 반환되는 함수를 변수에 담아 실행하면 기억하고 있는 환경(변수)에 의해 결과에 영향을 미친다.
위의 코드를 보면 closureTest()
함수를 호출할 때 인수 1
을 전달한다. closureTest()
함수에서는 param
으로 인자를 받아 x
라는 변수에 할당한다. 다음에 func
라는 변수에 closureTest()
함수에서 실행후 반환하는 함수가 대입된다. 반환하는 함수에서는 상위 스코프의 변수 x
를 사용한다. 이때의 변수 x
는 1
이 대입되어 반환되고 그 값을 기억하게 된다. 그리고 반환되는 함수는 매개변수를 받도록 설계되었다.
클로저(closure)는 내부에서 사용된 변수의 값을 기억한다.
이제 func(1)
, func(2)
함수가 차례대로 실행되어지는데 먼저 func()
함수를 호출하면서 인수 1
을 전달한다. 이 단계에서 func()
함수의 내부에서 사용하는 변수 x
는 이미 1
이라는 값을 기억하고 있다. 따라서 func()
함수를 호출할 때 인수 1
을 전달하면 x
에 전달된 매개변수 1
을 더한 뒤 x
에 다시 대입하여 반환한다. 이후 다시 func()
함수를 호출하면서 인수 2
를 전달하면 값이 변경된 변수 x
에 더한 뒤 다시 대입하여 반환한다.
보통 함수는 한번 실행하면 내부 변수의 값은 더 이상 의미가 없지만 closure(클로저)에 의해 처리되는 변수는 그렇지가 않다. 이 점을 로직에 활용하여 함수를 개발할 수 있다.