JavaScript_클로저(Closure)

Eugenius1st·2022년 7월 12일
0

JavaScript

목록 보기
13/62

클로저란?

"함수와 함수가 선언된 어휘적(lexical) 환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다."
"외부 함수의 변수에 접근할 수 있는 내부 함수"를 클로저 함수라고 한다.

클로저 함수의 특징


여기 평범한 덧셈을 하는 함수가 있다.

위와 같이 화살표를 두번 사용한다. 이는 함수의 호출을 두번한다.

이 말은 곧 adder의 리턴 값이 함수의 형태임을 의미한다.
즉. adder 는 함수를 리턴하는 함수이다.

클로저 함수의 기본 형태


클로저 함수의 첫 번째 특징은 함수를 리턴하는 함수라는 점이다.
함수를 리턴하는 함수가 클로저의 형태를 만든다.

클로저는 함수와 함수가 선언된 어휘의 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지를 먼저 이해해야 한다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

외부함수와 내부함수


클로저의 핵심은 스코프를 이용해서, 변수의 접근 범위를 닫는(closure)데에 있다. 따라서 함수를 리턴하는 것 만큼이나, 변수가 선언된 곳이 중요하다.


x가 선언 된 함수는 바깥쪽에 있으니 '외부함수'라 한다.

y가 선언된 함수는 보다 안쪽에 있으니 '내부함수'라 부른다. 따라서 이 클로저 함수는 스코프가 분리되어 있다.

이를통해 알 수 있는 클로저 함수의 특징은

'내부 함수는 외부 함수에 선언된 변수에 접근 가능하다.'
라는 점이다.

클로저의 활용

  • 데이터를 보존하는 함수
    : 외부함수(adder)의 실행이 끝나더라도, 외부함수 내 변수 x를 사용할 수 있다.
    외부함수의 실행이 끝나더라도 외부함수 내 변수가 메모리 상에 저장된다. 어휘적 환경을 메모리에 저장하기 때문에 가능하다. 변수 add5 에는 클로저를 통해 리턴한 함수가 담겨있다.

  • 예제 _ HTML 문자열 생성기

예제에서 divMaker함수는 div라는 문자열을 tag라는 변수에 담아두고 있으며, anchorMaker함수는 a라는 문자열을 tag에 담아두고 있다.
클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 해준다.

  • 정보의 접근 제한(캡슐화)_ 클로저 모듈 패턴

    클로저를 이용해 내부함수를 단 하나만 리턴하는 것에 그치지 않고, 객체에 담아 여러 개의 내부 함수를 리턴하도록 만든다.

makeCounter를 실행하여 변수에 담아보자

makeCounter 함수는 increase, decrease, getValue 메서드를 포함한 하나의 객체를 리턴한다. 따라서 counter1은 객체이다.


외부스코프는 내부 스코프의 변수에 접근할 수 없다 라는 규칙에 의해 어떤 경우에도 value는 직접 수정이 불가능하다.(캡슐화) 대신 리턴하는 객체가 제공하는 메서드를 통해 value를 간접적으로 조작할 수 있다.

이것이 정보의 접근 제한 (캡슐화)이다.

만일 스코프로 value 값을 감싸지 않았더라면, value 값은 전역 변수여야만 했을 것이다. 하지만 makeCounter라는 함수가 value값을 보존하고 있기 때문에, 전역 변수로 따로 만들 필요가 없다. 전역변수가 좋지 않은 이유는, 전역 변수는 다른 함수 혹은 로직등에 의해 의도되지 않은 변경을 초래하기 때문이다.

이를 side effect 라고 한다. side effect를 최소화 하면, 의도되지 않은 변경을 줄일 수 있다. 따라서 이에 따른 오류로부터 보다 안전하게 값을 보호할 수 있다.

클로저를 통해 불필요한 전역 변수 사용을 줄이고, 스코프를 이용해 값을 보다 안전하게 다룰 수 있다.

  • 모듈화_재활용 가능한 makeCounter 함수

    여러개의 counter를 만드는 것이 가능하다.

makeCounter 코드는 그대로 활용한다.

makeCounter를 실행할때 선언되는 value값을 각자 독립적으로 가지게 된다. 따라서 counter1 에서의 value와 counter2 에서의 value는 서로에게 영향을 끼치지 않고 각각의 값을 보존할 수 있다.

이를 모듈화 라고 한다.

예제


다음 코드의 실행 결과는 0 이다.
클로저 모듈 패턴의 예시이다. 변수 calue는 직접 수정하는 것이 불가능하고, 리턴하는 객체가 제공ㅇ하는 메서드를 통해서만 조작이 가능하다. 이렇게 캡슐화를 함으로써 변수 value를 makeCounter 함수로 보존해서 전역 변수로 인한 side effect를 방지할 수 있다.


result 값은 리턴한 20이다


result 는 전역에 선언된 x이다.


outer 함수는 전역변수 x 에 20을 재할당 한다. 따라서 result 값은 20이다. inner함수가 호출되긴 하지만 inner 함수는 바깥 스코프에 아무런 영향을 미치지 않는다.


seenYet이 반환하는 익명 함수는 외부 함수 seenYet의 스코프에 선언된 변수 archive에 접근할 수 있기 때문에 클로저입니다.

profile
최강 프론트엔드 개발자가 되고싶은 안유진 입니다

0개의 댓글