JS/JavaScript

#18 자바스크립트 클로저(Closure) 개념

인생아 2024. 9. 3. 23:47
반응형

자바스크립트에서 클로저(Closure)는 매우 중요한 개념 중 하나로, 함수와 함수가 선언된 어휘적 환경(Lexical Environment) 사이의 조합을 의미합니다. 클로저는 자바스크립트의 강력한 기능 중 하나로, 주로 함수 내부에서 정의된 변수를 외부에서 접근하거나 유지하고 싶을 때 사용됩니다.

이 글에서는 자바스크립트 클로저의 개념을 깊이 있게 설명하고, 실제 사용 예제를 통해 클로저가 어떻게 작동하는지 살펴보겠습니다.

클로저란 무엇인가?

클로저는 함수가 자신이 선언된 환경(scope)의 변수들을 기억하고, 그 환경에 접근할 수 있게 해주는 기능입니다. 즉, 클로저를 사용하면 함수가 자신이 생성될 때의 환경(스코프)을 "기억"하여, 함수가 생성된 이후에도 그 환경에 접근할 수 있습니다.

클로저의 기본 예제

function outerFunction() {
    let outerVariable = 'I am outside!';

    function innerFunction() {
        console.log(outerVariable);
    }

    return innerFunction;
}

const myClosure = outerFunction();
myClosure(); // "I am outside!"

위의 예제에서 innerFunction은 outerFunction 내부에 정의된 함수입니다. outerFunction이 실행되고 종료된 이후에도 innerFunction은 outerVariable에 접근할 수 있습니다. 이는 innerFunction이 outerFunction의 환경을 기억하고 있기 때문이며, 이 현상이 바로 클로저입니다.

클로저의 실제 활용 예제

클로저는 특정 데이터의 은닉화 및 유지가 필요할 때 자주 사용됩니다. 예를 들어, 다음과 같은 예제는 클로저를 활용하여 카운터를 구현합니다.

클로저를 활용한 카운터 예제

function createCounter() {
    let count = 0;

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

const counter = createCounter();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

이 예제에서는 createCounter 함수가 호출될 때마다 count 변수를 초기화하고, 내부 함수를 반환합니다. 반환된 함수는 count를 증가시키고 그 값을 반환하는 역할을 합니다. 중요한 점은 count 변수가 createCounter 함수 외부에서 접근할 수 없고, 오직 클로저 내부에서만 유지된다는 점입니다.

클로저와 함수의 스코프

클로저는 자바스크립트의 스코프 체인과 밀접한 관련이 있습니다. 함수가 선언된 위치에 따라 그 함수의 스코프가 결정되며, 클로저는 이 스코프 체인을 기억하여 언제든지 접근할 수 있게 합니다.

스코프 체인과 클로저 예제

function outerFunction() {
    let outerVariable = 'Outer';

    function innerFunction() {
        let innerVariable = 'Inner';
        console.log(outerVariable); // "Outer"
        console.log(innerVariable); // "Inner"
    }

    return innerFunction;
}

const closureFunc = outerFunction();
closureFunc();

위의 예제에서 innerFunction은 outerFunction 내부에 정의되어 있어, outerFunction의 변수 outerVariable에 접근할 수 있습니다. 반대로 outerFunction은 innerFunction의 변수에 접근할 수 없습니다. 이와 같은 스코프 체인과 클로저의 특성을 이해하면, 자바스크립트 함수가 어떻게 동작하는지를 더 깊이 있게 이해할 수 있습니다.

클로저의 메모리 관리

클로저는 함수가 더 이상 필요하지 않을 때에도 스코프 체인을 유지하기 때문에, 클로저를 사용할 때는 메모리 관리에 신경 써야 합니다. 잘못된 클로저 사용은 메모리 누수를 일으킬 수 있습니다.

메모리 관리에 대한 주의사항

function outerFunction() {
    let largeArray = new Array(1000000).fill('Hello');

    return function() {
        console.log(largeArray[0]);
    };
}

const closureFunc = outerFunction();
closureFunc(); // "Hello"
// largeArray는 여전히 메모리에 남아있음

위의 예제에서 largeArray는 클로저에 의해 메모리에 계속 유지됩니다. 만약 이러한 클로저가 많은 데이터에 접근하거나 오랜 시간 동안 유지된다면, 메모리 누수가 발생할 수 있습니다. 따라서 클로저를 사용할 때는 필요한 변수만 유지하고, 불필요한 데이터는 가능한 빨리 메모리에서 해제하는 것이 중요합니다.

클로저의 실전 활용

클로저는 다양한 상황에서 유용하게 활용될 수 있습니다. 예를 들어, 이벤트 핸들러나 비동기 작업에서 클로저를 사용하여 외부 변수에 접근하거나, 특정 데이터를 보호하는 데 사용할 수 있습니다.

이벤트 핸들러에서의 클로저 예제

function setupEventHandler() {
    let message = 'Event triggered!';

    document.getElementById('myButton').addEventListener('click', function() {
        alert(message);
    });
}

setupEventHandler();

위의 예제에서 message 변수는 setupEventHandler 함수가 종료된 후에도 click 이벤트 핸들러 내부에서 접근 가능합니다. 이는 클로저 덕분이며, 클로저를 통해 특정 데이터를 보호하면서도 이벤트 핸들러에서 사용할 수 있게 됩니다.

결론

자바스크립트에서 클로저는 함수와 그 함수가 선언된 환경 간의 관계를 활용하여 스코프 체인을 기억하고, 외부 함수의 변수에 접근할 수 있는 강력한 기능입니다. 클로저를 이해하고 적절하게 사용하면, 더 구조적이고 안전한 코드를 작성할 수 있습니다. 클로저는 특히 데이터 은닉화, 함수형 프로그래밍, 이벤트 핸들링 등의 상황에서 매우 유용하게 사용됩니다.

반응형