클로저 (Javascript)

Cramming An·2022년 7월 27일
0

JS Interview

목록 보기
5/7
post-thumbnail

클로저 란?

MDN의 정의

  • 클로저는 함수와 함수가 선언된 lexical environment의 조합이다.
  • 무슨말인지 모르겠다.
  • 우선 lexical environment에 대해 알아볼 필요가 있다.

렉시컬 스코프

  • 자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라, 어디서 정의했는지에 따라 상위 스코프를 결정한다.
  • this 바인딩과는 반대이다.
  • 함수를 정의한 위치에 따라 상위 스코프는 정적으로 결정됨
  • 이때, 상위 스코프란 현재 렉시컬 환경의 외부 렉시컬 환경에 대한 참조 라는 프로퍼티에 저장할 참조 값이다.
  • 그리고 외부 렉시컬 환경에 대한 참조 는 함수 정의가 평가되는 시점에 결정되므로 -> 함수를 어디서 정의했는지에 따라 상위 스코프를 결정한다.

함수 객체의 내부 슬롯 [[Environment]]

  • 외부 렉시컬 환경에 대한 참조를 저장하는 장소
  • 함수 객체의 내부 슬롯 [[Environment]]외부 렉시컬 환경에 대한 참조 가 저장되는 시점은 함수가 정의된 스코프에서 실행 컨텍스트가 실행될 때이다.
  • 이때 함수 객체가 생성이 되고, 함수 객체의 내부 슬롯[[Environment]] 에 지금 실행 중인 실행 컨텍스트의 렉시컬 환경에 대한 참조가 저장된다.
  • 이 후, 이 해당 함수의 실행 컨텍스트가 실행되고, 함수 렉시컬 환경을 설정할 때, 외부 렉시컬 환경 참조 프로퍼티에 함수 객체의 내부 슬롯 [[Environment]] 에 있던 값을 넣는다.

외부함수보다 중접함수가 더 오래 살아남을 때

  • 함수 foo()에 중첩 함수 boo()가 선언되고, 함수 foo()boo()를 리턴한다고 하자
  1. 함수 foo()의 외부 스코프의 실행 컨텍스트가 실행될 때, 함수 foo() 객체가 생성된다.
  2. 함수 foo()가 호출 되었을 때, 실행 컨택스트에 함수 foo()의 실행 컨택스트가 올라온다.
  3. 함수 foo()의 실행 컨택스트가 실행되면서, 함수 boo() 객체가 생성되고, 함수 boo() 객체의 내부 슬롯 [[Environment]]에 함수 foo()의 렉시컬 환경의 참조가 저장된다.
  4. 함수 foo()가 함수 boo()를 리턴하면 실행컨택스트 스택에서 함수 foo()의 실행 컨택스트가 빠진다. 따라서 함수 foo()의 렉시컬 환경이 접근할 수 없다.
  5. 하지만 함수 boo()를 담은 값이 함수 boo()를 호출하면 실행컨택스트 스택에 함수 boo()의 실행 컨택스트가 올라가고, 함수 boo() 객체의 내부 슬롯 [[Environment]]의 참조 값이, 함수 boo()의 외부 렉시컬 환경 참조에 저장이 된다.
  6. 이로써 함수 boo() 에서는 함수 foo()의 생존여부과 관계없이, 함수foo()의 렉시컬 환경이 접근 가능해진다.

이때 함수 boo()클로저 라고 부른다.

단, 외부 스코프의 어떤 식별자로 참조하지 않을 경우는 클로저가 아니다.

다시, 클로저 란?

  • 중첩함수가 상위 스코프의 식별자를 참조하고, 외부함수 보다 오래 유지되는 경우
  • 자유변수: 중첨함수가 참조하는 상위 스코프의 식별자

클로저의 활용

  • 상태를 안전하게 은닉하고, 특정 함수에게만 상태변경을 허용
const increase = function() {
  let num = 0
  return function() {
  	return ++num
  }
}
console.log(increase()) // 1
console.log(increase()) // 2
profile
La Dolce Vita🥂

0개의 댓글