Search

250311_2057_Closure(클로저)에 대하여

본 내용은 클로저에 대하여 계속해서 내용을 추가할 예정이며, 기입일을 기준으로 계속해서 내용 업데이트할 계획입니다.

Node.js 클로저(Closure)

클로저는 함수가 생성될 때의 렉시컬 스코프(lexical scope) 를 기억하고, 함수가 실행되는 동안에도 해당 스코프에 접근할 수 있는 기능
자바스크립트의 함수가 일급 객체(First-Class Object)이기 때문에 가능
비동기 프로그래밍, 데이터 은닉, 콜백 관리, 커링(currying) 등 다양한 패턴에서 사용됨
클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(Functional Programming language: 얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.

1. 클로저의 기본 개념

1-1. 렉시컬 스코프와 클로저

자바스크립트는 렉시컬 스코프(Lexical Scope)를 사용하여 변수를 찾음
함수가 선언될 당시의 스코프를 기억하며, 실행할 때에도 그 스코프에 접근 가능

예제 1: 기본적인 클로저 개념

function outer() { let count = 0; // 외부 함수의 변수 function inner() { // 내부 함수 count++; // 외부 변수 접근 가능 console.log(count); } return inner; // 내부 함수 반환 } const closureFunc = outer(); // outer 실행 -> inner 반환 closureFunc(); // 1 closureFunc(); // 2 closureFunc(); // 3
JavaScript
복사
설명
outer()가 실행되면 inner() 함수를 반환
closureFunc 변수는 inner()를 가리킴
inner()outer()count 변수에 접근 가능하며, 값이 유지됨

2. Node.js에서의 클로저 활용

2-1. 비동기 콜백에서 클로저

Node.js에서 클로저는 비동기 프로그래밍에서 자주 사용됨

예제 2: 비동기 콜백에서의 클로저

function delayedMessage(message, delay) { setTimeout(function() { console.log(message); }, delay); } delayedMessage("Hello, Node.js!", 1000); // 1초 후 출력
JavaScript
복사
설명
setTimeout의 콜백 함수는 message 값을 기억하여 일정 시간 후에도 접근 가능

2-2. 데이터 은닉 및 모듈화

클로저를 사용하면 특정 변수에 대한 직접 접근을 차단하여 데이터 은닉(encapsulation) 가능

예제 3: 데이터 은닉

function counter() { let count = 0; // 외부에서 접근 불가능한 변수 return { increment: function() { count++; console.log(count); }, decrement: function() { count--; console.log(count); } }; } const myCounter = counter(); myCounter.increment(); // 1 myCounter.increment(); // 2 myCounter.decrement(); // 1 console.log(myCounter.count); // undefined (직접 접근 불가)
JavaScript
복사
설명
count 변수는 counter() 함수 내부에 존재하며, 직접 접근할 수 없음
increment()decrement()count를 조작할 수 있음

2-3. 클로저를 이용한 커링(currying)

클로저를 활용하면 커링(Currying) 기법을 사용할 수 있음

예제 4: 클로저를 이용한 커링

function multiply(x) { return function(y) { return x * y; }; } const double = multiply(2); console.log(double(5)); // 10 console.log(double(10)); // 20 const triple = multiply(3); console.log(triple(5)); // 15
JavaScript
복사
설명
multiply(x) 함수는 x를 기억하는 클로저를 생성
doublemultiply(2) 실행 결과로 생성된 클로저를 저장하여 y 값을 입력받아 x * y 연산 수행

2-4. 클로저를 활용한 API 요청 제한

클로저를 활용하면 특정 요청의 빈도를 제한하는 레이트 리미터(rate limiter) 기능 구현 가능

예제 5: 요청 제한

function createRateLimiter(limit, interval) { let count = 0; let startTime = Date.now(); return function() { let currentTime = Date.now(); if (currentTime - startTime > interval) { count = 0; startTime = currentTime; } if (count < limit) { count++; console.log("Request allowed"); } else { console.log("Rate limit exceeded"); } }; } const request = createRateLimiter(3, 5000); request(); // Request allowed request(); // Request allowed request(); // Request allowed request(); // Rate limit exceeded
JavaScript
복사
설명
createRateLimiter(3, 5000)는 5초 동안 최대 3번만 요청 허용
request()가 호출될 때마다 현재 시간과 비교하여 제한 여부 결정

3. 주의할 점

3-1. 메모리 누수 가능성

클로저는 내부에서 참조하는 변수를 유지하므로, 불필요한 클로저 유지 시 메모리 누수 발생 가능
해결 방법: 더 이상 필요하지 않은 경우 클로저의 참조를 제거하거나, null로 설정

예제 6: 메모리 누수 방지

function createClosure() { let largeData = new Array(1000000).fill("data"); return function() { console.log(largeData.length); }; } const closureFunc = createClosure(); closureFunc(); // 1000000 // 메모리 해제 closureFunc = null;
JavaScript
복사
설명
closureFuncnull로 설정되면, largeData 배열도 해제됨

4. 정리

클로저는 함수가 생성될 당시의 스코프를 기억하고 유지하는 개념
비동기 콜백, 데이터 은닉, 커링, API 요청 제한 등 다양한 활용 가능
메모리 누수 방지 필요

참고자료

안녕하세요

관련 기술 문의와 R&D 공동 연구 사업 관련 문의는 “glory@keti.re.kr”로 연락 부탁드립니다.

Hello

For technical and business inquiries, please contact me at “glory@keti.re.kr”