JS | 클로저

5396 단어 JavaScriptJavaScript

클로저

어떤 함수에서 선언한 변수를 참조하는 내부함수에서 발생하는 현상

// 외부 함수의 변수를 참조하는 내부함수 1
function outer() {
    const a = 10;
    function inner() {
        debugger;
        const sum = a + a;
        console.log(a);
        console.log(sum);
    };
    inner();
}
outer();
// 외부 함수의 변수를 참조하는 내부함수 2
function outer() {
    const a = 10;
    function inner() {
        debugger;
        const sum = a + a;
        console.log(a);
        console.log(sum);
    };
    return inner;
}
const outer2 = outer();
outer2();

위의 두 함수 모두 내부 함수 inner에서 outerEnvironmentReference에 저장된 상위 컨텍스트 outer의 LexicalEnvironment에 접근하여 변수 a를 참조하고 있다.
첫번째 코드 같은 경우에는 outer의 실행 컨텍스트가 종료되면 LexicalEnvironment에 저장된 식별자 a와 inner에 대한 참조를 지우게 되는데
이때 각 값들은 참조하는 변수가 없어지게 되고 참조 카운트가 0이 되어 가비지 컬렉터의 수집 대상이 된다.

가비지 컬렉터 : 참조 카운트가 0인 메모리 주소의 값들을 수거한다.
(참조 카운트는 데이터를 참조하는 변수의 개수를 말한다.)

반면에 두번째 코드에서는 outer의 실행 컨텍스트가 종료된 이후에도 inner 함수를 호출할 수 있게 하였다.
호출되지 않고 return 된 inner 함수는 outer2 에 담겨 호출되고 outer의 실행 컨텍스트가 종료되어도 참조를 유지하게 된다.
두번째 코드와 같이 내부 함수가 외부 함수를 참조하는 경우에 외부 함수가 종료된 이후에도 변수가 사라지지 않는 현상을 클로저 라고 한다.



❓ 디버깅

위의 코드를 디버깅해보았는데 두 코드 모두 클로저 환경에 있다고 표현되어 있다.

첫 번째 코드에서처럼 단순히 내부 함수가 렉시컬 스코핑을 통해 상위 스코프를 참조하는 환경 자체도 클로저라고 말하는것인가..?

헷갈려서 찾아보니 내부함수 inner가 외부함수 outer의 식별자를 참조하고 있지만 inner를 반환하지 않았고,

inner의 생명주기가 outer 보다 짧아졌기 때문에 클로저의 본질에 부합하지 않아 일반적으로 클로저라고 부르지 않는다고 한다.

그렇다면 디버깅 화면에서 말하는 클로저는 클로저가 될 수 있는 가능성을 뜻하는 건가 🤔 ..!




📚 참고

코어자바스크립트
모던 자바스크립트 Deep Dive
자바스크립트의 스코프와 클로저

좋은 웹페이지 즐겨찾기