클로저, 함수는 태어난 곳을 기억한다.

Jaewoo Gwak·2022년 11월 8일
0

JavaScript

목록 보기
3/4
post-thumbnail

선행 지식

🧐 클로저란 무엇일까?

클로저는 외부 변수에 접근할 수 있는 함수이다.

자바스크립트에서 함수는 자신이 선언되었을 때의 렉시컬 환경을 기억하는데, 함수의 숨김 프로퍼티 [[Environment]]에 함수가 처음 선언된 위치의 렉시컬 스코프에 대한 참조가 존재한다.

아래 예시를 보자.

function makeCounter() {
  let count = 0; // here!
  return () => (count += 1);
}

const counter = makeCounter();
counter();
counter();
counter();
console.log(counter()); // 어떤 값이 출력될까요? -> 4

makeCounter()count += 1을 리턴하는 함수를 리턴한다

countermakeCounter()를 할당하면 count += 1을 리턴하는 함수가 할당된댜.

counter는 함수 표현식이 되며 함수를 실행시키면 count += 1이 작동한다.

이때 count가 존재하는 함수(makeCounter가 리턴하는 함수)가 생성된 곳의 렉시컬 환경을 기억하기 때문에 위 예시의 주석 here!에 해당하는 변수를 참조할 수 있다.

이때 count에 대한 참조는 숨김 프로퍼티 count.[[Enviroment]]에 저장된 렉시컬 환경이다. (이때 해당 렉시컬 환경은 함수가 처음 생성되었을 때의 렉시컬 환경이다)

즉, makeCounter가 리턴하는 () => (count += 1)은 외부 변수인 count에 접근할 수 있는 함수이자 클로저이다.

이러한 접근은 makeCounter의 스코프 밖에서도 가능하다.

counter를 호출할 때마다 count의 정보를 찾기 위해 makeCounter가 리턴하는 함수가 생성되었을 때의 렉시컬 환경에 존재하는 변수를 참조한다.

counter를 호출하면 count를 증가시키는데, 이 변화는 변수가 저장된 렉시컬 환경에서 이루어진다.

예시에서 주석이 달린 위치 here에서 값의 변화가 일어나는 것이다.

결국 함수 makeCounter의 스코프 밖에서도 count 값에 접근 가능하며 변경까지 할 수 있는 것이다. (클로저를 할당한 변수 counter의 호출을 통해!)

👼🏻 함수는 자신이 태어난 곳을 기억한다

자바스크립트의 함수는 자신이 태어난 곳을 기억한다. 함수가 호출될 때마다 새로운 렉시컬 환경이 생성되지만 변수에 대한 참조 위치는 숨김 프로퍼티 [[Environment]]로 동일하다.

그리고 함수를 호출하면 숨김 프로퍼티에 존재하는 count값을 변화시킨다.

결국 자바스크립트의 모든 함수는 클로저라 할 수 있다. 외부 변수를 참조하는 함수가 클로저니 말이다.

이제는 왜 앞선 예시에서 마지막 counter()가 리턴하는 값이 4인지 설명할 수 있다.

profile
꾸준하게 나아가고 싶다

0개의 댓글