moon palace

[Java Script] 클로저가 뭐야? closure에 대해 알아보자 본문

JavaScript

[Java Script] 클로저가 뭐야? closure에 대해 알아보자

Hdaleee 2020. 2. 29. 00:32

closure 함수라는 것이 있다. 말로 보자면 개념이 참으로 이해하기 어렵다. mdn에서는 '함수와 함수가 선언된 어휘적 환경의 조합'이라고 설명한다. 원문으로 보면 'A closure is the combination of a function bundled together (enclosed) with references to its surrounding state.' 해석해보면, 함수와 그 함수가 참조하는 값들이 묶여있는(에워쌓인) 상황을 일컫는다. 실질적인 예로서 함수 안에 변수와 그 변수를 참조하는 함수가 함께 들어가 있는 경우들을 볼 수 있다. 이 것이 왜 특수한 경우이고, 예외적이라고 부르며 특별하게 이름까지 지어서 따로 공부하는 걸까?


1. 스코프에 대한 이해(렉시컬 스코프 / lexical scope)
이전에 작성되었던 블로그(https://hdaleee.tistory.com/2?category=756750)를 통해 스코프에 대한 내용을 살짝 엿볼 수 있다(스크롤 중간쯤 '3. 스코프' 참조). 스코프란 간단히 이야기해서 어떤 변수나 값을 선언하였을 때, 그 선언된 값이 어디까지에 영향력을 미치는가를 정의한다고 볼 수 있다. var의 경우는 function scope로서 함수 단위로 구분되고, let과 const는 block scope로서 중괄호를 기준으로 구분된다. 이러한 상황에서 let이 나오기 전까지 var만을 가지고 함수 내에서 반복문을 작성할 때 문제가 발생했었는데, 이를 해결하기 위한 수단이 바로 클로저였다.

// var를 이용한 loop의 문제
function v(){
    for ( var i = 0 ; i < 3 ; i++ ){
        setTimeout( function(){
            console.log(i)
        },100)
    }
}
v()
// 3
// 3
// 3


// let을 이용한 loop
function l(){
    for ( var i = 0 ; i < 3 ; i++ ){
        setTimeout( function(){
            console.log(i)
        },100)
    }
}
l()
// 0
// 1
// 2

저 문제는 왜 발생하는 것일까? var가 함수 안에서만 존재하기 때문이다. var의 경우 함수가 '100'이라는 시간을 기다리면서 세 번 도는동안 계속 새로 갱신되어 최종값만이 세번 출력되었다. 하지만 let은 외부에 있는 function l(){}의 중괄호 안에 있는 동안 계속 값을 유효하게 정의하고 있기에 값이 살아있으면서 바뀌지 않고 기대하는 값을 출력해준다고 볼 수 있다.


2. 클로저의 활용
그러면 이제는 클로저를 사용할 일이 없을까? 그렇지는 않다. 클로저가 사용되는 활용 범위는 생각보다 넓다. 값을 상태를 유지하는 데에도 사용되고, 값을 숨겨두는 데에도 사용할 수 있다. 클로저는 특성상 함수 안에 내부함수를 만들고, 내부함수가 참조하는 값을 함께 선언한다. 그렇다는 것은 하나의 함수와 그 함수가 참조하는 값의 세트를 어떠한 함수안에 보관하는 것으로도 볼 수 있고, 개념적으로 보자면 그러한 보관방법은 자연스럽게 외부의 달라지는 환경에서부터 이들을 보호하는 것으로도 생각될 수 있다. 자세한 활용과 예시들은 다음 블로그에서 설명하도록 한다.

Comments