본문 바로가기
Front end/JavaScript

[JavaScript] 클로저 (closure)란 무엇일까

by re-hwi 2024. 11. 12.

모듈화의 핵심은 "응집도를 높히고 결합도를 낮춘다" 이다. 이 내용을 잘 생각하며 카운트를 증가시키는 함수를 만들어 본다면 어떻게 코드를 작성할 수 있을까

let cnt = 0;

function count(){
	return cnt ++
}

뭐 대충 이런식으로 작성할 수 있을 것이다. 이 때 cnt 변수가 함수 외부에 선언되었다. 이렇게되면 어떤 곳에서도 접근이 가능해 위험하고, count 함수를 다른곳으로 옮겨야 할때 항상 저 cnt 변수를 같이 가지고 가야하는 문제가 생긴다. 또 다른 경우에는 코드 200줄 아래에서 누군가가 cnt라는 변수를 사용한다면 에러가 날 수도 있다. 

 

이 때 cnt라는 변수를 count 함수 내부에 선언할 수만 있다면 위 문제 모두 해결된다. 그렇지만 count 함수를 호출할 때마다 cnt가 0으로 초기화되어 정확히 카운트를 할 수 없게된다. 이러한 문제점을 해결하기 위해 클로저가 탄생했다.

 

어떻게 클로저가 이러한 문제를 해결할 수 있을까? 바로 js 에서의 함수는 일급객체이기 때문이다. JavaScript에서 함수는 일급 객체이므로 함수의 반환값으로 사용할 수 있다. 클로저는 이 특성을 이용하여 내부 변수(cnt)를 외부에서 직접 접근하지 못하게 하면서, 함수가 외부 상태를 유지하게 만든다.

 

그럼 앞선 코드를 클로저를 이용해 작성해 보자

function createCounter() {
    let cnt = 0;

    return function() {
        return cnt++;
    };
}

const counter = createCounter();
console.log(counter()); // 0
console.log(counter()); // 1

 

이렇게 하나의 함수 내부에 카운트를 증가하는 function을 선언하여 해당 함수를 내보내 외부에서 사용할 수 있게 된다. 

 

이제 count를 1까지 올린 뒤 또 다른 변수를 createCounter를 사용하여 만들어보자.

function createCounter() {
    let cnt = 0;

    return function() {
        return cnt++;
    };
}

const counter = createCounter();
console.log(counter()); // 0
console.log(counter()); // 1

const _counter = createCounter();
console.log(_counter());
console.log(_counter());

아래의 새로 생긴 _counter를 사용한다면 다시 0이 출력된다. 새로운 메모리에 createCounter를 실행하기 때문에 cnt는 새로운 초기값으로할당된다. 

 

클로저를 배우며 느낀점은 getter와 setter를 사용해서만 접근이 가능한 데이터들을 보호하는 모습이 약간 클래스의 private랑 비슷한 느낌인 것 같았다.  

반응형

댓글