[Javascript] 클로저(Closure)

bareum park·2021년 10월 18일
0

Javascript

목록 보기
4/4
post-thumbnail

이번에 페어프로그래밍을 진행하며, 우리가 자주 접할 수 있는 기능들을 실제로 구현하는 시간을 가졌다. 간단하게 생각했던 기능들도 실제로 구현하려니 생각해야 하는 부분이 많아 무척이나 어렵게 느껴졌다. 많은 부분들이 힘들었지만 가장 어려웠던 부분은 클로저의 적절한 사용이었다. 이론적으로는 알고 있었으나 실제로 구현함에 있어 어려움을 많이 느껴 클로저에 대해 다시 한 번 정리해보고 짚고 넘어가려고 한다.

클로저

클로저는 자바스크립트의 고유 개념은 아니다. 함수를 일급 객체로 취급하는 함수 프로그래밍 언어에서 사용되는 중요한 특성이다. 클로저는 외부 함수와 중첩 함수가 있을 때, 외부 함수보다 중첩 함수의 생명주기가 길고, 외부 함수의 식별자를 하나 이상 참조 하고 있는 중첩 함수를 클로저라고 부른다.

외부 함수가 호출되고 종료되면, 외부 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 사라진다. 하지만 중첩 함수가 밖으로 return되어 외부 함수보다 생명주기 길고, 실행이 끝난 외부함수의 식별자를 참조하고 있다면 외부함수의 렉시컬 환경은 소멸되지 않는다. 이 경우 이미 소멸한 외부 함수의 식별자는, 이 식별자를 참조하고 있는 중첩 함수만 접근하여 변경 할 수 있게 된다.

이러한 클로저는 언제 사용될까? 바로 상태를 안전하게 변경하고 유지하기 위해 사용한다. 상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해서 사용하는 것이다.

클로저를 온전하게 이해하기 위해서는 렉시컬 스코프와 실행 컨텍스트에 대한 이해가 동반되어야 한다. 스코프와 실행 컨텍스트 역시 깊은 공부와 이해가 필요한 부분이나, 본 글에서 모두 정리 할 수 없으므로 간략하게 정리했다.

렉시컬 스코프

자바스크립트 엔진은 함수가 언제 호출되었느냐가 아닌, 함수가 언제 정의되었느냐에 의해 상위 스코프가 결정된다. 이를 렉시컬 스코프(정적 스코프)라고 한다. 자바스크립트는 데이터 타입이 런타임에 정해지는 동적 언어라는 것을 먼저 배우기 때문에 헷갈릴 수 있으니, 타입은 동적으로 함수의 상위 스코프는 정적으로 정해짐을 잘 기억해야 한다.

실행 컨텍스트

실행 컨텍스트는 소스코드를 실행하는 데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다. 식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고 코드 실행 순서는 실행 컨텍스트 스택으로 관리한다.

실행 컨텍스트는 4가지 소스 코드에 의해 생성되는데, 1. 전역 코드, 2. 함수 코드, 3. eval 코드, 4. 모듈 코드가 그것이다. 각각 전역 실행 컨텍스트, 함수 실행 컨텍스트, eval 실행 컨텍스트, 모듈 실행 컨텍스트가 생성된다.

즉, 위의 4가지 소스 코드를 제외하고는 실행 컨텍스트를 만들지 않는다. ES6부터 let과 const 키워드를 사용하면 if문, for문도 스코프를 갖는다. 스코프를 갖는다는 것은 렉시컬 환경이 생성된다는 것일 뿐, 실행 컨텍스트가 생성된다는 것은 아니다.

물론 실행 컨텍스트 생성 시 반드시 렉시컬 환경이 함께 생긴다. 하지만 렉시컬 환경이 생긴다고 해서 반드시 실행 컨텍스트가 생성되는 것은 아님을 잘 기억하고 구분 할 줄 알아야 한다.

결론

꽤나 긴 시간동안 자바스크립트 이론에 대해 깊게 배웠고, 이 배움을 통해 자바스크립트에 대해 제법 깊은 이해를 했다고 생각했다. 그런데 막상 실전에서 사용하려고 하니 다소 막막하게 느껴지기도 했고, 생각처럼 구현되지 않기도 했다.

이론과 구현의 갭을 채우기 위해서는 더 많이, 자주 구현해야 할 것 같다. 그리고 구현하는데에 급급해 하지 않고 배운것을 되짚고, 실제로 어떻게 적용 할 것인가에 대한 고민을 더 많이 해야 실제로 내 것이 된다는 것도 깨닫게 되었다.

그리고 이론과 실제 구현의 갭을 메꾸기 위한 공부의 시작을 클로저로 해야겠다고 생각했다. 클로저의 활용은 상태 관리를 위해서 필수적으로 필요한 부분이고, 내가 느끼기에 유난히 어려웠던 부분이기도 했기 때문이다. 앞으로도 꾸준히 공부하고 구현에 적용해서 클로저를 잘 다룰 수 있도록 할 것이다.

참조
MDN-closure
모던 자바스크립트 Deep Dive

0개의 댓글