[자바스크립트] 클로저, 가비지컬렉션

hoonie·2021년 9월 3일
0
post-thumbnail

안녕하세요. 이번 시간에는 자바스크립트 단골 면접 질문이자 핵심개념인 클로저에 대해 알아보겠습니다.

클로저란?

  • 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수
  • 자바스크립트에선 모든 함수가 클로저임

코드 살펴보기

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

let counter = makeCounter();

//0
console.log(counter())
//1
console.log(counter())
//2
console.log(counter())
  1. 다음과 같이 makeCounter라는 함수를 만들고,
  2. 그 안에 count라는 변수를 0으로 선언 초기화를 했다.
  3. 그리고 중첩함수를 사용하여 그 안에 count를 1씩 증가시키는 함수를 return 하는 함수를 만들었다.
  4. 그리고 makeCount()이라는 함수를 실행시키고 counter라는 변수에 선언 초기화 할당을 하였다.
  5. 그 이후 해당 변수를 연속으로 실행시켜보면 안에있는 count가 1씩 늘어나느 것을 확인 할 수 있다.

우리가 여기서 봐야할 개념은 어떻게 함수를 실행시켰는데 그 안에 있는 렉시컬 환경이 그대로 남아서 그거를 계속 참조하고 있느냐는 것이다.

우리가 중요하게 알아야 할 개념은 모든 함수는 함수가 생성된 곳의 렉시컬 환경을 기억한다는 점입니다. 함수는 [[Environment]]라 불리는 숨김 프로퍼티를 갖는데, 여기에 함수가 만들어진 곳의 렉시컬 환경에 대한 참조가 저장됩니다.

따라서 counter.[[Environment]]엔 count = 0인 렉시컬 환경에 대한 참조가 저장됩니다. 함수가 자신이 태어난 곳을 기억할 수 있는 건 바로 이 [[Environment]] 프로퍼티 덕분이며, 딱 한 번 값이 세팅되고 영원히 변하지 않습니다.

counter()를 호출하면 각 호출마다 새로운 렉시컬 환경이 생성됩니다. 그리고 이 렉시컬 환경은 counter.[[Environment]]에 저장된 렉시컬 환경을 외부 렉시컬 환경으로서 참조합니다.

때문에 makeCounter가 실행되고 종료가 되었음에도 계속해서 그 환경을 참조하여 count 값을 유지시키는 것입니다.

가비지 컬렉션 이란?

  • 기본적으로, 함수 호출이 끝나면 함수에 대응하는 렉시컬 환경이 메모리에서 제거됨.
  • 때문에 함수 호출이 끝나면 관련 변수를 참조할 수 가 없음.
  • 하지만 호출이 끝난 후에도 여전히 도달 가능한 중첩 함수가 있음
  • 이 경우에는 중첩함수의 [[Environment]] 프로퍼티에 외부 함수 렉시컬 환경에 대한 정보가 저장된것임
  • 함수 호출은 끝났지만 렉시컬 환경이 메모리에 유지되어 클로저가 발생하는 경우가 이때문임
  • 즉, 가비지 컬렉션은 함수 호출이 끝나서 렉시컬 환경이 메모리에서 사라졌고, 그 메모리에 더 이상 아무것도 참조되어있지 않은것을 컴퓨터가 알아서 메모리에서 삭제시켜주는 것임. 가비지 컬렉션이 없다면 시스템 메모리 할당량이 계속 커져 부하가 일어남

0개의 댓글