그럴듯한 개발 블로그
Published 2024. 1. 30. 23:35
클로저 <language>/javascript
반응형

c, c++ 만 해 본 나로선 클로저라는 머싯는 이름을 붙이는 게 이해가 안 갔다.
이거 그냥 함수 포인터 리턴하는 거 아니냐??라고 생각했다.
 
허나 아래 같은 상황에서는 애매하다.

function createCounter() {
    let count = 0;
    return function() {
        count += 1;
        return count;
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

counter변수에 담긴 createCounter 내부에 선언되어 리턴된 function의 경우 counter 변수가 참조하고 있으므로 인스턴스가 살아있는 게 맞지만, 함수 createCounter의 변수 count의 경우 이미 스택에서 사라진 메모리인데 segmentation fault아니냐이거??
 
그렇지 않다. 클로저의 경우 리턴하는 함수가 참조하고 있는 모든 환경(가장 상위 depth의 스코프까지)을 캡쳐한다. (한 몸이다 얘 죽을 때 다 같이 죽음)
그냥 해당 스코프만큼의 인스턴스가 살아있다고 생각하면 편하다
 
이는 나름대로 쉽게 설명한 거고 멋진 설명도 첨부한다.

  1. 렉시컬 환경의 유지: createCounter 예시에서 내부 함수(클로저)는 createCounter 함수의 렉시컬 환경을 "캡처"합니다. 이 렉시컬 환경에는 count 변수가 포함됩니다.
  2. 생명주기 공유: 내부 함수는 **createCounter**의 렉시컬 환경을 참조하므로, 이 환경은 내부 함수가 존재하는 동안 계속 유지됩니다. 즉, count 변수는 내부 함수의 생명주기와 같이합니다.
  3. GC의 역할: 내부 함수가 count 변수를 참조하는 한, 가비지 컬렉터는 이 변수를 메모리에서 해제하지 않습니다. 내부 함수가 더 이상 접근할 수 없거나, 참조가 사라지면, 그때서야 GC가 이 변수를 청소할 수 있습니다.

정말인지 확인해 보자 못 믿겠다

function createCounter() {
    let count = 0;
    return function() {
        count += 1;
        let count2 = count;
        return function() {
            return count2;
        };
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

진짜네..

반응형

'<language> > javascript' 카테고리의 다른 글

js는 비동기 큐가 2개다?  (1) 2024.03.26
profile

그럴듯한 개발 블로그

@donghyk2

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!