본문 바로가기
🟨 JavaScript 🟨

JavaScript - Closure(클로저)

by 백씨네 2024. 2. 21.
728x90

Closure

클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다. 클로저는 자바스크립트에서 매우 중요한 개념으로 함수가 생성될 때의 환경을 기억하게 해 주며, 이를 통해서 여러 패턴, 기법을 구현할 수 있다.

클로저의 정의와 작동원리

  • 클로저는 함수가 선언된 시점의 스코프에 있는 모든 변수에 대한 참조를 유지한다.
    • 함수가 실행될 때마다 해당 스코프에 접근할 수 있음을 의미한다.
  • 클로저는 함수가 실행되어 외부 스코프에서의 실행이 종료되어도 해당 함수의 스코프 내에 선언된 변수들에 대한 접근을 가능하게 한다.
    • 자바스크립트의 함수는 외부 스코프에 정의된 모든 변수에 접근할 수 있다.

클로저 예시


function outerFunction (arg) {
    var variableInOuterFunction = arg

    function bar() {
        console.log(variableInOuterFunction)
    }

    bar()
}

outerFunction("hello closure")

내부 함수가 외부 범위에서 변수에 액세스 하려는 것을 확인할 수 있다.
외부 함수의 변수는 내부 함수에 의해 닫혔거나 바인딩되었다.

 

클로저는 함수가 선언될 때의 주변환경을 기억하는 함수 라고 할 수 있다.

이를 통해 함수는 자신이 생성될 때의 환경에 있던 변수들을 기억하여 나중에도 계속 접근할 수 있다.

 

모듈 패턴 같은 객체를 쉽게 구성할 수 있다.


function createCounter() {
    let val = 0;
    return {
        increment() { val++ },
        getVal() { return val }
    }
}

let counter = createCounter();
counter.increment();
console.log(counter.getVal()); 
counter.increment();
console.log(counter.getVal()); 

 

이 패턴은 데이터를 캡슐화하고 공개 인터페이스를 통해 데이터에 접근하는 방법을 제공한다.

 

'createCounter' 함수는 'val'이라는 변수를 가지고 있으며, 이 변수는 함수가 반환하는 객체의 'increment' 메서드와 'getVal' 메서드를 통해서만 접근이 가능하다. 'createCounter' 함수가 호출될 때마다 새로운 'val' 변수가 생성되고, 이 변수는 각각의 counter 인스턴스에 대해 고유하다.

외부에서 직접 접근할 수 없게 함으로써 데이터를 안전하게 보호한다.

클로저의 이점

  • 메모리 효율성 : 특정 데이터에 대한 접근을 필요한 함수에만 제한하여 메모리 사용을 최적화할 수 있다.
  • 코드의 모듈성과 재사용성 증가 : 공통 기능을 가진 함수를 쉽게 생성하고 재사용할 수 있다.

클로저 주의사항

  • 메모리 누수 : 클로저를 부적절하게 사용하게 되면 사용하지 않은 메모리가 해제되지 않아 메모리 누수가 발생한다.
  • 성능 고려사항 : 불필요한 메모리 사용을 피하기 위해서 적절히 사용해야 한다.

클로저의 이점과 주의사항을 보면 메모리 효율성메모리 누수가 쓰여있다.

메모리를 효율적으로 쓰는데 누수가 생긴다..?

 

 

클로저의 사용 방식에 따라 두 가지 특성이 공존할 수 있다.

메모리 효율성

클로저는 특정 함수에서만 필요한 데이터에 대한 접근을 제한함으로써 메모리를 효율적으로 사용할 수 있게 해 준다. 예를 들어, 클로저를 사용하여 특정 함수에 대한 설정이나 상태를 저장하는 경우, 이 데이터는 해당 함수가 실행될 때만 메모리에 유지되고, 다른 부분의 코드에서는 접근할 수 없기 때문에 메모리를 절약할 수 있다.

함수가 실행될 때마다 필요한 데이터를 생성하고 불필요할 때는 자동으로 정리하여 메모리 사용을 최소화한다.

메모리 누수

반면, 클로저를 부적절하게 사용하면 누수가 발생할 수 있다. 클로저는 외부 함수의 변수에 대한 참조를 유지하기 때문에, 이 변수들은 내부 함수가 살아 있는 한 가비지 컬렉터에 의해 수집되지 않는다.

만약 클로저가 큰 데이터 구조를 참조하고 있고, 이 클로저가 오랜 시간 동안 메모리에서 제거되지 않는다면, 필요하지 않은 데이터가 메모리에 계속 남아 있게 되어 메모리 누수가 발생할 수 있다.

 

 

효율적인 클로저 사용법

  • 클로저가 필요한 경우에만 사용하고, 불필요한 참조를 피해야 한다.
  • 큰 데이터 구조를 참조하는 클로저는 주의해서 사용해야 하며, 가능한 한 생명주기를 짧게 유지해야 한다.
  • 클로저를 사용한 후에는 클로저가 참조하는 외부 변수를 해제하거나 null로 설정하여 가비지 컬렉터가 수집할 수 있도록 해야 한다.
반응형

댓글