[JS] 렉시컬 환경, 클로저 이게 뭘까?

Ganziman·2025년 2월 11일
4
post-thumbnail

JS 공부하다가 잘 이해가 안 되는 개념이 있어서 이 꼭두새벽에 기억해 보려고 글을 적어 보았다...(깊은 한숨)

다른 분들께서 잘 정리해 주신 글을 봐도 잠깐 이해한 듯하다가, 다음 날 기억이 삭제되고 누가 물어보면 절대 대답 못 할 것 같아 글로 남겨보기로 했다.

렉시컬 환경(Lexical Environment)이란?

코드가 실행될 때 그 코드가 접근할 수 있는 변수와 함수들(그에 해당하는 값)을 기억하고 주변 스코프들을 관리하는 구조이다

을 의미한다.

렉시컬 환경은 크게 두 가지로 나뉜다:
1. 환경 레코드
2. 외부 렉시컬 참조(상위 스코프)

이 말대로라면, 아래 코드를 기준으로 설명해보자.

function a() {
  let aVari = 3;

  function b() {
    let bVari = 3;
    console.log(aVari + bVari); // 6
  }
  b()
}
a()

여기서 특정 코드를 함수 b()라고 가정하면, 함수 b()의 환경 레코드외부 렉시컬 참조는 무엇일까?

1. 함수 b()의 환경 레코드
함수 b() 내부에는 bVari라는 변수가 선언되어 있다.
따라서 환경 레코드는 bVari를 포함한다.
만약 함수 b()에 매개변수가 있었다면, 그 매개변수도 환경 레코드에 포함될 것이다.

2. 함수 b()의 외부 렉시컬 참조
함수 b()는 함수 a() 내부에 선언되어 있다.
그래서 외부 렉시컬 참조는 함수 a()의 렉시컬 환경, 즉 함수 a()의 환경 레코드를 가리킨다.
함수 a()의 환경 레코드에는 aVari가 포함되어 있다.

결론적으로
함수 b()의 환경 레코드는 bVari
함수 b()의 외부 렉시컬 참조는 함수 a()의 환경 레코드, 즉 aVari 이다.

그래서 함수b()의 입장에서 이렇게 구성된 환경 덕분에 함수a() 환경에 접근할 수 있다.


그러면 일단 여기까지는 어떻게든 이해해봤어.
그러면 함수b()는 어떻게 함수a() 즉, b()의 상위스코프에 접근할 수 있을까??

이때 나오는 개념이 클로저(closure)이다.

클로저(Closure)란?

렉시컬 환경에 대한 참조와 함께 묶인 함수의 조합
즉, 내부 함수에서 외부 함수의 범위에 대한 접근을 제공

MDN의 출처에 따르면 Javascript에서 클로저는 함수 생성 시 함수가 생성될 때마다 생성된다.
그렇다, 클로저라는 것이 생겼다.
함수b()와 함수b()가 참조하는 외부 변수들을 (함수b()의 상위 스코프)포함한 렉시컬 환경 전체가 클로저를 의미한다.

이 덕분에 함수b()의 상위 스코프(외부 함수의 범위 또는 외부로 참조하는 렉시컬 환경)인 함수a()를 참조할 수 있어 aVari 변수에 접근할 수 있게 된거다.
(그러면 쉽게 말해 자바스크립트 이니까 접근이 가능한거구나!!!)

그렇다면 여기서 개념을 이해했으니

좀 더 살짝만 맛보도록 해보자.

다음 내용은 MDN에서 클로저에 대한 설명 중
예제 코드를 기반으로 수정해보았다.

function makeAdder(x) {
  return function (y) {
    return x + y;
  };
}

const add5 = makeAdder(5);

console.log(add5(2)); // 7

클로저의 한 예제 코드이다.
왜 클로저일까?

const add5는 makeAdder의 내부함수(function(y) ...)를 반환한다.
그 뒤에 add5(2)를 실행했다.
그러면 add5는 내부함수(function(y)...) 매개변수로 2를 넣었다.
그러면 처음에 넣었던 x값 5(기억한거임)를 더해서 7이 된거다.

근데 눈대중으로 볼 때 코드상에서는 makeAdder은 끝났는데 어떻게 x값이 있을 수가 있을까??

위에서 말했듯 클로저는 내부 함수가 외부 함수를 참조할 수 있어 makeAdder의 환경 레코드인 x값을 기억하고 있기 때문이다.

다른 분들의 좋은 관련글들을 보면서 이해도 되었고 직접 작성하고 나니 조금이나마 렉시컬 환경과 클로저에 대해 알게 되었다

Reference

profile
GanziMan 입니다.

1개의 댓글

comment-user-thumbnail
2025년 2월 12일

범님 덕분에 이해가 쏙쏙 ^^

답글 달기