• [JS] 자바스크립트 클로저(Closure)

    2023. 3. 19.

    by. 지은이: 김지은

    728x90

     

    클로저(Closure)란?

    클로저는 자바스크립트의 모든 함수가 갖고 있는 특성 중 하나다.

    이 클로저를 이해하려면 변수의 스코프(Scope)개념을 알고있어야한다.

    스코프(Scope)란?
    자바스크립트에서 변수는 선언된 위치에 따라 해당 변수에 접근할 수 있는 범위가 결정된다.

    1. 전역 스코프(Global Scope): 전역 스코프에 선언된 변수는 어디에서나 접근 할 수 있다. 
    2. 지역 스코프(Local Scope): 함수 내에서 선언된 변수는 해당 함수 내에서만 접근할 수 있으며, 함수 내부에서 선언된 변수는 외부에서 접근할 수 없다.

     

    클로저를 간단히 말하자면, 함수가 다른 함수 내에서 정의되고, 외부 함수의 변수를 참조할 때 클로저가 생성된다.

    이때 외부 함수의 변수는 클로저에 의해 기억되며 함수가 종료되어도 클로저를 통해 해당 변수에 계속 접근할 수 있다.

     

    const outer = function() {
        let a = 1;
        const inner = function() {
            console.log(++a); // a에 접근
        }
        inner();
    }
    outer(); // 2 출력

    outer 함수에 'a'라는 지역변수를 선언하고, 함수 내부에 inner 함수가 있다.

    이때  a는 inner함수 내에 선언하지 않았지만, 자신을 포함하고 있는 외부 함수 outer에서 변수 a에 접근 가능하여 2가 출력된다.

    inner함수가 outer 함수의 변수 'a'를 사용해서 값을 변경하고 출력할 수 있는 것이 클로저라고 한다.

     

    const outer = function() {
        let name = 'john';
        const inner = function() {
            alert(name); // name에 접근
        }
        return inner;
    }
    const outer2 = outer();
    outer2(); // john 출력

    이번에도 outer 함수 안에 있는 inner 함수에서 외부 변수 name을 사용하려고 하고, outer함수는 inner 함수 자체를 return 하고 있다.

    그래서 outer 함수가 호출되면 내부 함수인 inner가 반환되고 이걸 outer2에 할당한다.

    그리고 inner함수가 outer에 있는 변수인 name에 접근해서 john을 출력한다.

    이때 outer 함수 실행이 끝나도 클로저를 형성항 inner 함수는 여전히 name변수에 접근할 수 있는데 이게 클로저라고 한다.

     

    위 과정에서 클로저가 어떻게 형성이 되는지?!

    1. outer 함수가 호출될 때 렉시컬 환경이 생성되며, 이 환경엔 name 이라는 변수와 그 값이 저장된다.

    2. inner 함수가 정의될 때 클로저가 형성되는데, 이는 외부 함수인 outer의 렉시컬 환경을 참조해서 name 변수에 접근할 수 있게 한다.

    3. inner 함수가 반환될 때 이 함수는 클로저를 형성한 상태로 반환되기 때문에 inner 함수를 호출해도 클로저를 통해 여전히 외부 변수 name에 접근할 수 있게 된 것

     

    클로저 장점

    접근 권한 제어가 가능하다.

    자바스크립트는 변수 자체에 접근 권한을 직접 부여할 수 없다. 하지만 return을 활용하여 외부에 제공할 정보는 return, 내부에만 사용할 정보는 return을 하지 않게 하여 접근 권한을 제어할 수 있다.

     

    클로저 단점

    함수가 종료되어도 메모리엔 남아있다.

    그래서 사용하지 않는 클로저에 대해 메모리를 차지 하지 않도록 관리해야 하는데 null, undefined를 할당해주어 참조를 끊으면 된다.

     

    Refernece

    • 코어 자바스크립트

     

    댓글