[JS] 클로저

yoon Y·2022년 6월 3일
0

JS 학습 내용 정리

목록 보기
5/7

클로저란?

  • 외부 함수의 변수를 참조하는 내부함수를 외부로 전달했을 때, 그 내부함수가 존재하는 동안은 외부함수의 실행컨텍스트가 제거되어도 참조되는 변수는 남아있게 되는 현상
  • 이미 종료된 외부함수의 내부 변수를 참조하는 함수
  • 클로저는 자신이 생성될 때의 환경(Lexical Envoriment)을 기억하는 함수라고 정의할 수 있다.

클로저의 원리

  • 함수가 저장될 때 [[Environment]] 속성에 자신이 선언된 외부 함수의 렉시컬 환경을 연결한다.
  • 내부 함수가 실행되어 실행 컨텍스트를 만들 때 자신의 [[Environment]]값을 이용하여 외부 환경에 부모함수의 렉시컬 환경을 연결한다. (내부 함수가 언제 어디서 실행되던 자신이 선언된 환경을 기억할 수 있는 이유)
  • 원래 함수 실행이 종료되면 가비지 콜렉터가 해당 함수의 실행컨텍스트를 제거하지만, 내부 함수의 [[Environment]] 속성이 부모함수의 렉시컬 환경을 참조하고 있으므로 제거되지 않고 남아있게 된다.

주의점

  • 클로저를 제거하고 싶다면 그것을 참조하고있는 함수를 제거하면 된다.
    해당 함수의 메모리 주소를 담고있는 변수에 다른 값(null)을 넣어 더이상 참조되지 않도록 할 수 있다.
  • 클로저가 된 값도 변할 수 있다. 메모리에 아직 있기 때문에
  • 꼭 리턴만이 외부전달이 아니다. 외부함수 안에서 내부함수를 webapi의 콜백으로 전달하는 경우도 외부 전달이다.

클로저 활용 사례

  • 모듈이 없었을 때 전역변수의 접근과 중복 선언을 막기 위해 즉시실행함수를 사용하여 내부변수를 캡슐화하는 용도로 사용 → 함수 내부에서만 사용하고 싶은 private변수를 정의하고 싶을 때 클로저를 활용했다.
  • 정의된 스코프 이외의 곳에서 사용할 때 private 저장소처럼 사용할 수 있다.

헷갈렸던 점

1. 외부 환경 참조는 함수가 실행될 때 구성되는 데 어떻게 함수가 선언됐을 때의 컨텍스트를 아는가?

함수 선언이 저장될 때 숨김 속성인 [[Environment]]에 선언된 컨텍스트를 기억해 놓고, 해당 함수가 실행될 때 외부 환경 참조 속성에 [[Environment]]을 연결한다.

js의 함수는 일반 객체 + 함수로 동작하기 위한 기능이 추가된 것이다.
함수 객체는 다음과 같은 데이터들을 내부에 추가로 저장한다.

프로퍼티
1. 클로저로 묶이는 렉시컬 환경(Lexical Environment) - [[Environment]]
2. 함수 코드 - [[ECMAScriptCode]]
3. 함수 종류 - [[FunctionKind]]: "normal", "classConstructor", "generator", "async"
4. 생성자 종류 - [[ConstructorKind]]: "base", "derived"
5. this 참조 형태 - [[ThisMode]]
6. strict mode 여부 - [[Strict]]
7. super 참조 - [[HomeObject]]
8. 기타 등등

메소드
실제로 함수를 실행시켜주는 [[Call]], [[Construct]] 
함수를 호출하면 함수 객체 내부의 [[Call]]이 호출되고, 
new 또는 super 연산자와 함께 호출하면 [[Construct]]가 호출된다.

함수의 저장과 실행
함수 선언 시 저장되는 것들은 함수 자체에 대한 정보들이다.
내부 코드들은 그 자체로 통째로 저장된다.

함수가 실행되면 메모리에 저장된 함수 자체 정보에서 코드를 읽으면서 자신의 내부 변수를 저장하고 [[Environment]] 로 참조되는 부모 환경을 outEnvironment로 연결한다.

profile
#프론트엔드

0개의 댓글