본문 바로가기
Language/JavaScript

클로저 | Closures

by Krystal K 2023. 10. 17.

클로저  | Closures

 

[index]

1. 클로저란?

2. 실행컨텍스트 관정에서 본 클로저

3. 클로저의 활용 사례

4. 클로저와 관련된 문제점

5. 결론


 

1. 클로저(closures)란?

1-1. 클로저에 대한 정의

클로저는 자신이 생성될 때의 렉시컬 환경(Lexical environment)을 기억하는 함수

 

함수와 그 함수가 선언되었을 때의 렉시컬 환경(어휘적 환경)의 조합이다.

선언되었을 때란, 내부 함수가 선언되었을 때를 지칭한다.

주변 상태(어휘적 환경)에 대한 참조나 함께 묶인(포함된) 함수의 조합을 의미한다.

 

MDN 에서의 클로저의 정의는 다음과 같다.
A closure is the combination of a function enclosed with references to its surrounding state(the lexical environment).  In other words, a closure gives you access to an outer function's scope from an inner function.

 

1-2. 클로저란 무엇인가?

클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(Functional Programming language: Scala, Erlang, etc..)에서 사용하는 중요한 특성이다.

 

내부함수가 자신을 포함하고 있는 외부함수보다 더 오래 유지되는 경우, 외부 함수 밖에서 내부 함수가 호출되어도 외부 함수의 지역변수에 접근할 수 있는데, 이 때 접근하는 내부함수를 클로저라고 한다.

 

클로저는 반환된 내부함수가 자신이 선언되었을 때의 환경인 스코프를 기억하여 자신이 선언 됐을 때의 환경 밖에서 호출되어도 그 환경에 접근할 수 있는 함수를 의미한다. 

쉽게말해, 클로저는 자신이 생성될 때의 환경을 기억하는 함수이다.

 

closure라는 이름의 의미
자유 변수에 엮여있는 함수(closed)

자유 변수(Free variable)
클로저에 의해 참조되는 외부함수의 변수

 

 

2. 실행 컨텍스트의 관점에서 본 클로저

자바스크립트에서 함수가 생성될 때, 해당 함수의 실행 컨텍스트(Execution Context)가 생성된다. 이 때 실행 컨텍스트에는 함수가 선언될 때의 렉시컬 환경 정보도 함께 저장된다. 이 렉시컬 환경 정보를 기억하는 것이 바로 클로저이다.

 

클로저의 동작 원리는 스코프 체인(Scope Chain)에 기반한다. 클로저를 사용하는 함수는 외부 함수의 스코프(렉시컬 환경)에 대한 참조를 기억한다. 때문에 클로저를 통해 함수 내부에서 외부 함수의 변수에 접근할 수 있다 .

 

1. 외부 함수 종료 -> 외부 함수의 실행컨텍스트 반환

2. 내부 함수는 유효한 상태

3. 외부 함수 실행 컨텍스트 내의 활성 객체는 내부 함수에 의해 참조되는 한 유효

4. 스코프 체인을 통해 내부함수가  자유변수를 참조

 

실행 컨텍스트에 대한 글 보러가기

 

 

3. 클로저의 활용 사례

클로저는 다양한 상황에서 활용될 수 있다. 그 중 가장 대표적인 활용 사례는 다음과 같다.

 

3-1. 상태 유지(State Retention)

클로저를 사용하면 현재 상태를 기억하고 변경된 상태를 유지할 수 있다. 내부 함수에서 외부 함수의 변수에 접근할 수 있기 때문에, 함수가 종료된 이후에도 해당 변수에 접근하여 값을 유지할 수 있다. 이를 통해 상태 값을 계속 유지하면서 함수를 호출할 때 해당 상태 값을 참조할 수 있다 .

 

예를 들어, 클릭 이벤트가 발생할 때마다 카운트를 세주는 함수가 있다고 가정해봅시다. 클로저를 사용하지 않는다면 전역 변수로 count를 사용해야 한다. 그러나 클로저를 사용하여 외부 함수의 변수인 count를 참조하는 함수를 반환한다면, 전역 변수 없이도 클로저를 통해 상태 값을 유지할 수 있다 .

 

3-2. 전역 변수의 사용 억제

클로저를 사용하면 전역 변수의 사용을 억제할 수 있다. 전역 변수는 어디에서나 접근할 수 있어서 예기치 않은 결과를 초래하기도 한다. 클로저를 사용하면 변수가 함수 스코프 내에 한정되므로, 함수 외부에서 변수에 접근할 수 없게 된다. 이를 통해 코드의 예측 가능성을 높이고 변수의 충돌을 방지할 수 있다. 상태 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에서 부수 효과(Side Effect)를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이기 위해 클로저 사용할 것을 권한다.

 

3-3. 정보의 은닉

클로저를 사용하면 정보를 은닉할 수 있다. 자바스크립트에서는 함수 스코프를 가진 변수는 외부에서 접근할 수 없다. 이를 이용하여 함수 내에 변수를 선언하고, 클로저를 반환하여 외부로부터의 접근을 차단할 수 있다. 정보 은닉을 통해 변수에 대한 직접적인 접근을 제한하고, 필요한 경우에만 접근할 수 있도록 제어할 수 있다 .

 

3-4. 자주 발생하는 실수 방지

클로저를 사용하면 발생할 수 있는 일부 실수를 방지할 수 있다. 예를 들어, 반복문 내에서 비동기 함수를 사용하는 경우, 클로저를 활용하여 각 반복 때마다 해당 반복 변수를 유지할 수 있다. 이렇게 하면 비동기 콜백 함수에서 해당 반복 변수를 제대로 참조할 수 있고, 예상치 못한 결과를 방지할 수 있다.

 

4. 클로저와 관련된 문제점

클로저는 자바스크립트와 스위프트 같은 여러 프로그래밍 언어에서 유용하게 사용되는 개념이다. 그러나 클로저는 사용할 때 주의해야 할 몇 가지 문제점이 있을 수 있다. 이 문제점들은 메모리 소모, 퍼포먼스 저하, 가독성 저하, 클로저 재사용의 어려움 등으로 요약할 수 있다.

 

4-1. 메모리 소모

클로저를 사용하면 클로저가 참조하는 외부 변수나 객체에 대한 참조를 유지해야 한다. 이로 인해 필요 이상으로 메모리를 소모할 수 있다. 특히 클로저가 대규모의 데이터나 복잡한 객체를 참조하는 경우에는 이 문제가 더 심각해질 수 있다.

 

4-2. 퍼포먼스 저하

클로저는 새로운 스코프를 생성하고 내부 함수와 외부 환경을 연결하는 과정이 필요하다. 이로 인해 함수 호출 속도가 느려질 수 있다. 특히 반복문이나 루프에서 클로저를 사용하는 경우에는 퍼포먼스가 더욱 저하될 수 있다.

 

4-3. 가독성 저하

클로저는 여러 줄에 걸쳐 작성되는 경우나 중첩된 클로저를 사용하는 경우 등에는 가독성이 떨어질 수 있다. 코드의 구조를 파악하기 어려워지고 디버깅이 어려워질 수 있다. 특히 클로저가 전달되는 위치가 함수 호출의 매개 변수로 인해 복잡해질 수 있다.

 

4-4. 클로저의 재사용 어려움

클로저는 주로 일회성으로 사용되는 경우가 많기 때문에 같은 클로저를 여러 번 재사용하기 어려울 수 있다. 클로저 자체를 변수나 상수에 할당하거나 다른 함수의 인자로 전달하는 방법을 사용하여 이 문제를 해결할 수 있지만, 코드가 복잡해질 수 있다.

 

5. 결론

클로저는 자바스크립트에서 함수가 생성될 때 형성되는 렉시컬 환경과 함수의 실행 컨텍스트를 기억하는 중요한 개념이다.  내부 함수가 외부 함수의 변수에 접근할 수 있는 클로저의 특성을 잘 이용하여 코드를 구성한다면,  상태 유지, 전역 변수의 사용 억제, 정보 은닉, 실수 방지 등 다양한 상황에서 유용하게 활용할 수 있다.

 

또한 클로저의 문제점들은 언어마다 차이가 있을 수 있으며, 사용 상황에 따라 다를 수도 있다. 따라서 클로저를 사용할 때에는 메모리 소모나 퍼포먼스, 가독성 등을 고려하여 적절히 사용해야 한다. 클로저가 필요한 경우에는 클로저의 장단점을 이해하고 적절히 활용하는 것이 중요하다.

728x90