JS Closure

Younchong·2021년 10월 14일
0

Closure

  • 정의

클로져란 어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달시 A의 실행컨텍스트가 종료된 이후에도 변수 a가 사라지지않고, 기억하고 접근할 수 있는 것을 의미한다.
(코어JS, JS info 출처) 다양하게 설명했지만, 제일 이해가 잘 됐다.

  • 활용 사례
  1. 접근권한 제어(은닉)
    변수를 접근을 어렵게 해서 오류를 방지. 안정성
    전역변수 사용 억제
  1. 상태 유지
    현재 상태를 기억하고 변경된 최신상태 유지.

Lexical Environment

함께 이해해야될 부분

렉시컬환경은 두부분으로 구성

  1. Environment Record (환경 레코드)
    모든 지역변수들을 프로퍼티로 저장, this정보
  1. Outer Lexical Environment
    외부코드와 연관된 정보들

Lexical Environment는 함수 호출시 새롭게 자동으로 만들어진다.
그 내부엔 함수 호출시 넘겨받은 매개변수, 함수의 지역변수가 저장됨.

  • 함수를 반환하는 함수
    모든 함수는 함수가 생성된 곳의 렉시컬환경을 기억하는데, [[Environment]] 숨긴 프로퍼티로 함수가 만들어진 곳의 렉시컬 환경에 대한 참조가 저장됨.
    [[Environment]] 프로퍼티는 함수 생성시에 딱 한번 생성되고 값이 변하지 않는다.

그래서 이 [[Environment]]프로퍼티로 함수가 처음 생성된 곳을 알 수 있게 하고 스코프 체인과 같이 Lexical Environment에서 변수를 찾고 없으면 상위, 즉 outer Lexical Environment 이동해 변수를 참조합니다.
이떄 변숫값 갱신은 변수가 저장된 Lexical Environment에서 됩니다.


function outer() {
  let count = 0;
  let inner = function () { 
    console.log(count++);
  }

return inner;
}

let countMachine = outer();
countMachine();
countMachine();
countMachine();


여기 console에 적힌 값은 0, 1, 2 로 나올 것이다.
이때 countMachine가 실행될때마다 새로운 lexical Environment가 생긴다.
이 lexical Environment는 countMachine.[[Environment]]를 외부 렉시컬 환경으로 참조하게 되고,
count라는 변수가 countMachine에는 없기때문에 외부 렉시컬환경을 참조해서 outer에 있는 count를 사용합니다.
이 변수 count++함으로 (갱신된 변숫값은 저장된 곳에서 변함) 계속 count값이 저장되고 업데이트된다.

  • 유의점

메모리 누수
GC(Garbage Collector)가 코드가 실행되고(함수호출이 끝나고) 함수에 대응하는 렉시컬환경이 메모리에서 제거된다. 이때 변수들도 모두 사라짐.
하지만 클로저를 이용하게 되면 외부함수 사용이 끝나더라도 내부함수에서 외부함수의 변수를 사용하고 있기 때문에 GC가 제거하지 못해서 메모리사용이 계속 된다.
(렉시컬 환경이 유지됨)이로 인해 생기는 메모리 누수를 없애기 위해서는 사용이 끝난 클로저 함수를 (위의 코드를 예시로) countMAchine = null;
삭제해주면 메모리에서 삭제된다.

0개의 댓글