볼 때마다 헷갈리는 Closure 정복하기

wkawhaRo·2024년 3월 9일
0

Closure란?

클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생성 시 함수가 생성될 때마다 생성됩니다.

MDN 공식문서에 나온 정의는 위와 같다.

  • 주변 상태(어휘적 환경)에 대한 참조
  • 함께 묶인 함수

의 조합이라고 하는데 말이 너무 어려워서 예시 코드를 보며 이해해 보았다.

예제 1

function init() {
  var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
  function displayName() {
    // displayName() 은 내부 함수이며, 클로저다.
    console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
  }
  displayName();
}
init();

일단 위 정의에서 나온 ‘클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공’하는 부분을 통해 displayName 이 클로저임을 알 수 있다.

why?

init 함수의 내부 함수이며, displayName 함수는 본인 외부에 있는 변수 name 을 참조하고 있기 때문이다.

그런데 저 예제의 흐름을 보면

  1. init 함수를 실행
  2. 내부에서 displayName 함수를 실행
  3. console.logname 을 찍기 때문에 사실 클로저라고 보기 어렵다.

예제2

다음 코드를 보자.

function init() {
  var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
  function displayName() {
    // displayName() 은 내부 함수이며, 클로저다.
    console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
  }
  return displayName();
}
const test = init();
test();

자, 위 예제에 대한 흐름을 보자

  1. testinit 함수 호출하며 할당
  2. initdisplayName 함수를 반환하면서 종료됨
  3. testdisplayName 함수를 가지게 됨
  4. test 를 실행하여 displayName 함수를 실행
  5. 이 때, init 함수는 종료되면서 지역변수인 name존재하지 않는다
  6. 하지만 closure인 displayName 는 생성될 당시의 name 을 참조하게 된다.
  7. 고로 콘솔창에는 “Mozilla” 값이 나오게 된다!!

displayName 이 생성되는 시점(9번째 라인)에서 initname 을 참조한다. 이것이 함수 생성 시 주변 환경(어휘적 환경)을 참조하는 것이다.

정리

💡 Closure는 함수가 선언될 때의 환경을 기억하여 이 함수가 다른 스코프에서 호출될 때에도 기억했던 환경(변수 등)에 접근할 수 있게 하는 JavaScript의 특징이다
profile
1일 1백준을 목표로

0개의 댓글

관련 채용 정보