클로저란?

이의섭·2022년 3월 14일
0

면접

목록 보기
3/4

다양한 서적에서 클로저를 한 문장으로 요약해서 설명하는 부분들을 소개하면 다음과 같습니다.

  • 자신을 내포하는 함수의 컨텍스트에 접근할 수 있는 함수 - 더글라스 크록포드
  • 함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 것 - 에단 브라운
  • 함수를 선언할 때 만들어지는 유효범위가 사라진 후에도 호출할 수 있는 함수 - 존 레식
  • 이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 함수 - 송형주, 고현준
  • 자유변수가 있는 함수와 자유변수를 알 수 있는 환경의 결합 - 에릭 프리먼
  • 로컬 변수를 참조하고 있는 함수 내의 함수 - 야마다 요시히로
  • 자신이 생성될 때의 스코프에서 알 수 있었던 변수들 중 언젠가 자신이 실행될 때 사용할 변수들만을 기억하여 유지시키는 함수 - 유인동

위의 여러 문장들중에서 저는 3번째(존 레식)의 문장이 가장 와닿는다고 생각합니다.

저는 클로저는 내부(중첩된)함수에서 외부함수의 변수에 접근할 수 있는 특성이라고 간단하게 정의합니다. 즉, 쓰임이 끝난 외부함수일지라도 내부함수가 외부함수의 변수를 참조하고 있다면 외부함수는 GC의 대상이 되지 않아 메모리 해제가 이뤄지지 않는다고 합니다.

함수가 실행될 때, 실행 컨텍스트가 생성된다는것을 주목해야 합니다. 실행 컨텍스트는 렉시컬 환경과 this바인딩이 담겨있고, 렉시컬 환경에서 환경 레코드와 외부환경참조 정보가 저장된다고 했습니다. 외부환경참조에 의해 변수의 유효범위인 스코프가 결정되고 스코프 체인이 가능해지기 때문에 클로저와 같은 현상이 발생하게 됩니다.

정리

즉 클로저란, 어떤 함수 A에서 선언한 변수a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상으로 정리할 수 있습니다.

메모리 누수

앞서 클로저로 인해 개발자의 의도와 달리 어떤 값의 참조 카운트가 0이 되지 않는 메모리 누수가 발생할 수 있지만, 개발자가 잘 파악해서 적용하면 누수가 일어나지 않습니다. 참조 카운트를 0으로 만들면 언젠가 GC가 수거해갈 것이고, 이때 소모됐던 메모리가 회수되겠습니다. 해제하는 방법은 식별자에 참조형이 아닌 원시형 데이터(보통 null, undefined)를 할당하면 됩니다.

접근 권한 제어(정보 은닉)

let createCar = function(){
  let fuel = Math.ceil(Math.random() * 10 + 10);
  let power = Math.ceil(Math.random() * 3 + 2);
  let moved = 0;
  return {
    get moved() {
      return moved;
    },
    run: function() {
      let km = Math.ceil(Math.random() * 6);
      let wasteFuel = km / power;
      if (fuel < wasteFuel) {
        console.log("이동불가");
        return;
      }
      ...
    }
    };
  }
  
  let car = createCar();

이렇게 하면 그저 객체로 선언하는것이 아니기때문에 이제 외부에서는 fuel이나 power, moved같은 변수에 대한 접근이 불가능해지게 됩니다.

profile
사용자 중심 생각하는 프론트엔드 개발자가 되고 싶은..

0개의 댓글

관련 채용 정보