클로저란 무엇인가요?
Last updated
Last updated
자바스크립트에서 클로저란 함수가 선언될 때 생성된 렉시컬 환경을 기억하고, 함수가 실행되는 시점에도 그 환경에 접근할 수 있는 기능을 말합니다. 쉽게 말하면, 함수가 자신이 선언된 스코프의 변수에 계속 접근할 수 있도록 해주는 개념입니다.
예를 들어, 어떤 함수 안에서 또 다른 함수를 선언하고, 이 내부 함수가 외부 함수의 변수를 참조한다면, 이 내부 함수는 클로저가 됩니다. 중요한 점은 외부 함수가 실행을 끝내더라도, 내부 함수는 외부 함수의 변수에 접근할 수 있다는 것입니다.
클로저는 주로 상태를 유지하거나, 변수 값을 은닉하는 데 활용됩니다. 예를 들어, 카운터를 구현할 때 클로저를 사용하면 외부에서는 직접 접근할 수 없고, 내부 함수만 상태를 변경하거나 읽을 수 있습니다. 이런 방식으로 데이터 보호나 특정 로직 캡슐화가 가능합니다.
결국 클로저는 자바스크립트에서 변수를 더 안전하고 효율적으로 관리할 수 있게 도와주는 중요한 기능입니다.
자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는데, 이를 렉시컬 스코프(정적 스코프)라고 합니다.
MDN는 클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다. 라고 정의하고 있습니다.
자바스크립트의 함수는 자신이 정의된 환경에 의해 결정된 상위 스코프의 참조, 즉 렉시컬 환경에 대한 참조를 자신의 내부 슬롯 [[Environment]]에 저장합니다.
(이미지 출처: 모던 자바스크립트 딥다이브)
MDN의 예시 코드입니다. 다음과 같은 코드에서, displayName()은 클로저가 됩니다. 이유는 name은 init에 의해 생성된 지역 변수이지만, displayName() 함수가 이를 스코프체인을 타고 올라가 상위 스코프의 name변수에 접근 할 수 있기 때문입니다.
클로저의 핵심은 상위 함수가 종료되었음에도, 하위 함수가 상위 함수의 변수를 참조할 수 있다는 점입니다. 실제 클로저가 동작하기 위해서는 아래 코드와 같이 작성할 수 있습니다.
자바스크립트의 모든 함수는 스코프 체인을 통해 상위 스코프를 기억하므로 이론적으로는 모든 함수가 클로저라고 할 수 있겠습니다! 하지만 만약 상위 스코프의 아무것도 참조하지 않는다면 그것은 메모리 낭비일 뿐 클로저라고 하기 어렵습니다.