[JS] 클로저(Closure)란?

유나영·2023년 3월 20일
0

JavaScript

목록 보기
1/4
post-thumbnail

클로저란?

클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.

MDN에서 정의한 클로저는 위와 같습니다. 하지만 말이 너무 어렵네요...!!
우선 렉시컬 환경이 무엇인지부터 알아야겠군요.

렉시컬 환경(Lexical environment)이란?

함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 스코프가 결정되는 것을 렉시컬 스코핑(Lexical scoping)라 합니다.

아래의 예시 코드를 보겠습니다.

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  innerFunc();
}

outerFunc(); // 10

어떻게 10이라는 결과값이 나올 수 있는 걸까요? 아마 자바스크립트 엔진은 다음과 같은 과정을 거쳤을 것 입니다.

  1. innerFunc 함수 스코프내에서 변수 x를 검색한다.
    검색 실패
  2. innerFunc 함수를 포함하는 외부 함수 outerFunc의 스코프에서 변수 x를 검색한다.
    검색 성공!

이처럼 내부함수 innerFunc가 자신을 포함하고 있는 외부함수 outerFunc의 변수 x에 접근할 수 있는 것, 다시 말해 상위 스코프에 접근할 수 있었던 것은 (렉시컬 스코프의 레퍼런스를 차례대로 저장하고 있는) 실행 컨텍스트의 스코프 체인을 자바스크립트 엔진이 검색하였기에 가능한 것입니다.

이번에는 내부함수 innerFunc를 함수 outerFunc 내에서 호출하는 것이 아니라 반환하도록 변경해보겠습니다.

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}

/**
 *  함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
 *  그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
 */
var inner = outerFunc();
inner(); // 10

함수 outerFunc는 내부함수 innerFunc를 반환하고 생을(?) 마감했습니다.
즉 함수 outerFunc는 실행된 이후 콜스택(실행 컨텍스트 스택)에서 제거되었으므로 함수 outerFunc의 변수 x 또한 유효하지 않게됩니다.
다시 말해서 변수 x에 더이상 접근을 할 수가 없다는 얘기입니다.
하지만 위의 코드를 실행해보면 inner의 값은 10이 됩니다.
분명 접근을 할 수 없어야하는데 말이죠..!

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

따라서 위의 “함수가 선언될 때의 렉시컬 환경(Lexical environment)”란 내부 함수가 선언됐을 때의 스코프를 의미합니다. 즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경밖에서 호출되어도 그 환경에 접근할 수 있는 함수를 말합니다. 여기서 환경이란 스코프와 동일한 의미로 보시면 되겠습니다.

클로저를 사용하는 이유

클로저라는 것이 무엇인지 알아봤으니 이를 왜 쓰는지도 알아봅시다. 쓰면 좋은 이유가 있으니 쓰는 것이 아니겠습니까.

1. 전역변수를 줄일 수 있다.

전역변수를 남용하는 것은 메모리 낭비로 이어지기 때문에 지양하는 것이 좋습니다. 하지만 우리는 종종 이 함수 내에서만 사용되는데 전역으로 변수를 선언해줘야하는 경우가 생깁니다. 이럴때 클로저함수가 아주 유용하게 활용할 수 있겠죠?

2. 모듈화에 유리하다.

클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용하고 보존할 수 있습니다.이와 같이 함수의 재사용성을 극대화 함수 하나를 독립적인 부품의 형태로 분리하는 것을 모듈화라고 하는데요, 클로저를 통해 데이터와 메소드를 묶어다닐 수 있기에 클로저는 모듈화에 유리하다고 볼 수 있습니다.


마치며

사실 더 자세히 공부하고 기록하고 싶었으나 공부를 하면서 추가로 알게 되는 점은 수정하자는 마인드로 우선 1차로 작성. 특히 클로저를 사용하는 이유에 대해서는 직접 예제 코드도 작성해보면서 100퍼센트 이해할때까지 다시 꼭 공부해야겠다.
현재 임시 저장글에만 작성하고 올리지 못한 글이 너무 많아서 짧게짧게라도 우선 올리자! 하는 마음으로 업로드.. 📚

참고
https://velog.io/@proshy/JS%ED%81%B4%EB%A1%9C%EC%A0%B8closure%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%B8%EC%9D%98-%EC%82%AC%EC%9A%A9-%EC%98%88%EC%A0%9C

https://poiemaweb.com/js-closure

https://hanamon.kr/javascript-%ED%81%B4%EB%A1%9C%EC%A0%80/#:~:text=%E2%9D%97%EF%B8%8F%EC%9E%A5%EC%A0%901.%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC,%EC%9E%88%EA%B2%8C%ED%95%98%EB%8A%94%20%ED%8F%90%EC%87%84%EC%84%B1%EC%9D%84%20%EA%B0%96%EB%8A%94%EB%8B%A4.

profile
프론트개발자입니다.

0개의 댓글