반응형

안녕하세요. 신기한 연구소입니다.

이번 포스팅은 자바스크립트의 중요한 개념 중 하나인 클로저(closure)에 대해 알아봅니다.

사실 클로저(closure)는 자바스크립트에서만 사용하는 개념은 아니고 함수형 프로그램에서 사용하는

중요한 부분입니다.

단순히 책을 보고 이해하기 어려운 부분이 있기에 좀 더 쉽게 설명해보려고 합니다.

그럼 클로저(closure)가 무엇인지 알아보도록 합니다.

사전적 의미는 폐쇄입니다.

우선 자바스크립트의 클로저(closure)를 이해하기 전 알아야 할 개념이 있습니다.

바로 렉시컬 스코프(lexical scope)입니다.

2021.09.05 - [Software/JavaScript] - [왕초보]자바스크립트에서 사용하는 렉시컬 스코프 쉽게 이해하기. JavaScript lexical scope.

 

[왕초보]자바스크립트에서 사용하는 렉시컬 스코프 쉽게 이해하기. JavaScript lexical scope.

안녕하세요. 신기한 연구소입니다. 자바스크립트를 공부하면 Scope(스코프)를 만나게 되는데요. 그중 렉시컬 스코프(lexical scope)의 의미가 참~이해하기 힘들더군요. 그래서 이번 포스팅은 렉시컬

tiboy.tistory.com

미리 읽어보고 오시면 좋겠네요.

자바스크립트는 함수의 스포크를 정할 때 어디서 실행했는지가 아닌 어디에 정의했는지에 따라서

상위 스코프를 정한다고 했습니다. 바로 이것을 렉시컬 스코프(lexical scope)라고 합니다.

 

그럼 클로저(closure)를 먼저 정의해보겠습니다.

어떤 함수가 있습니다.

그 함수 안에는 내부 함수가 존재합니다.

그 함수는 내부 함수의 상위 함수라고 부르겠습니다. 

내부 함수는 상위 함수의 지역 변수에 접근할 수 있습니다.

하지만 상위 함수는 내부 함수의 지역 변수에 접근할 수 없습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
function outerFunc(){
    var a = 1;
 
    function innerFunc(){
        var b = 2;
        console.log(a + b);
    }
 
    console.log(a + b);
}
 
outerFunc();
 
cs

위 예제를 보면 9라인에서 오류가 납니다. 

innerFunc의 b에 접근할 수 없기 때문입니다.

클로저는 이렇게 내부 함수가 외부 함수의 지역 변수에 접근해서 사용을 합니다.

그리고 외부 함수보다 내부 함수의 수명이 길어야 합니다.

즉 외부 함수를 호출 한 뒤 외부 함수는 수명을 다해서 사라지더라도

내부 함수는 렉시컬 스코프를 유지하면서 외부 함수의 변수를 계속 참조하고 있어야 합니다.

또한 외부 함수의 지역 변수에 바로 접근을 할 수 없지만 클로저를 통해서

접근 및 사용이 가능하게 됩니다.

그리고 그 외부 함수의 지역 변수의 값을 유지해 줍니다.

다음 예제로 확인해 봅니다.

클로저를 만드는 방법 중 하나입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function outFunc(){
    var a = 1;
 
    function inFunc(){
        return a++;
    }
 
    return inFunc;
}
 
var testFunc = outFunc();
 
console.log(testFunc());
console.log(testFunc());
cs

먼저 외부 함수 outFunc를 선언하고

지역 변수 a를 설정합니다.

이 지역 변수 a는 현재 외부 함수에서만 사용 가능합니다.

이제 내부 함수 inFunc를 선언하고

렉시컬 스코프 범위의 외부 함수의 지역 변수인 a에 ++연산을 해서 접근합니다.

그리고 외부 함수는 내부 함수 자체를 객체로 리턴합니다.

 

11라인을 보면 외부 함수 outFunc()를 변수 testFunc에 담았습니다.

이제 이 전역 변수는 outFunc()의 리턴된 내부 함수 inFunc를 참조하게 됩니다.

13과 14라인을 실행하면 outFunc의 지역 변수 a를 ++로 연산한 값을 받게 됩니다.

초기화되지 않고 연결해서 1, 2가 출력됩니다.

 

바로 이 내부 함수가 클로저입니다.

전역 변수 testFunc()에 담기는 상황에 outFunc()는 return으로 내부 함수 inFunc()를 넘겨주고

수명을 다하게 됩니다.

그럼 지역 변수 a도 같이 사라지게 되겠지요?

하지만 내부 함수에서 외부 함수의 지역 변수인 a를 참조하고 있고

이 범위를 렉시컬 스코프라 하는데

내부 함수가 외부 함수의 렉시컬 스코프를 갖고 있는 겁니다.

그래서 외부 함수의 수명이 다 했더라도 외부 함수의 지역 변수가

클로저(내부 함수)에 의해 참조되고 있으니 사라지지 않고 유지가 되는 겁니다.

 

자바에서 클래스 내부의 private로 선언된 변수를 getter/setter로 접근하는 방식과

비슷해 보입니다.

 

값을 숨겨두고 정의됨 함수에서만 그 값을 컨트롤할 수 있는 기능이

자바스크립트에서는 클로저로 가능하겠네요.

 

클로저(closure)의 의미에 대해 살펴봤습니다.

이제 클로저를 어떤 방식으로 만들고 사용하면 좋을지 고민할 시간이네요.

다음 포스팅에서 이 부분을 다뤄볼 생각입니다.

 

개발자는 팔로워가 아니라는 글이 생각납니다.

개념도 모르고 이해도 못한 상태에서 그냥 검색해서 남이 만든 소스를 그냥 가져 나르는(팔로잉) 팔로워가 아닌

개념도 정리하고 확실히 이해한 뒤 직접 구현하거나 검색해서 찾은 소스를 이해하고 제대로 사용하는

개발자(디벨로퍼)가 돼야겠습니다.

내일 또 개발이 아닌 정치?? 하러 회사에 출근합니다.

아~ 재미없네요. ㅎㅎㅎ

반응형