개발 기록이

[JavaScript] 클로저(Closure) 란? 본문

기록/JavaScript

[JavaScript] 클로저(Closure) 란?

studyingbackhoe 2024. 7. 6. 14:31

1. 클로저의 개념

함수가 정의될 때의 렉시컬 환경을 기억하여 함수가 실행될 때 그 환경의 변수들에 접근할 수 있게 하는 특성.
 
이 문장만 보면 무슨 의미인지 이해하기가 어려우니 간단한 예시 코드를 통해 하나씩 뜯어보자.
클로저에 대한 설명은 다음과 같다.

  • 외부 함수의 변수를 내부 함수에서 사용할 때 클로저가 생성.
  • 해당 변수의 값이 외부 함수 변수에서 선언한 값으로 초기화되지 않고도 사용 가능.
  • 클로저는 외부 함수의 스코프를 기억하고 있어서, 외부 함수가 종료된 이후에도 내부 함수에서 외부 함수의 변수에 접근할 수 있음.

 

(예시 코드)

const func = (function() {
    let cnt = 0;
    
    return function() {
        console.log(cnt++);
    };
})();

func(); // 0
func(); // 1
func(); // 2

 
1. 외부 함수: func 함수
2. 내부 함수: return 되는 익명함수 (func이라는 함수 안에 있는 함수)
 
return 되는 함수(내부 함수)에서 외부함수의 cnt 변수를 사용하고 있는데 func();을 실행할 때마다 cnt값이 0으로 초기화될 것 같지만 실제 코드를 실행해 보면 0으로 초기화되지 않고 cnt값이 1씩 증가하고 있다. 그 이유는 클로저가 외부 함수의 스코프를 기억하고 있어서 그 값(cnt 값)을 계속 기억하여 func()을 실행할 때마다 cnt 값이 1씩 증가하기 때문이다.
 
 

그렇다면 왜 자바스크립트에서 클로저가 생기게 되는 걸까?

 
 

2. 클로저가 생기는 이유

자바스크립트의 함수는 일급 객체(first-class object)이며 "렉시컬(lexical) 스코프"를 따르기 때문이다.

 
*일급 객체
함수를 변수에 할당하거나 함수의 매개변수로 전달하거나 함수를 반환하는 것과 같은 작업이 가능하다는 의미
 
* 렉시컬(lexical) 스코프 (=정적 스코프)
함수가 어디서 호출되었는지가 아니라 "어디에 정의되었는지"에 따라 변수의 스코프가 결정되는 것을 의미
 
* 동적 스코프
렉시컬 스코프와 반대 개념으로, 어디에 정의되어 있는지가 아닌 변수가 "어디에서 호출되었는지"에 따라 스코프를 결정하는 방식을 의미
 
 

함수가 일급 객체이기 때문에 함수는 다른 함수 내부에서 정의가 될 수 있으며, 이때 외부 함수의 변수를 내부 함수에서 사용할 수 있게 된다. 이때 내부 함수는 외부 함수의 스코프를 기억하고 있어서, 외부 함수가 종료된 이후에도 외부 함수의 변수에 접근할 수 있게 된다. 

즉, 함수 A 내부에서 함수 B를 정의하고, 함수 B 내부에서 변수를 참조한다고 가정해 보자. 이때 함수 B가 어디서 호출되었는지가 아니라 함수 B가 정의된 위치에 따라 변수의 스코프가 결정되기 때문에 함수 B는 함수 A의 스코프를 포함하여 함수 A 내부의 변수들에 접근할 수 있게 된다. 이러한 동작 방식은 렉시컬 스코프 때문에 가능한 것이다.
 
 
클로저를 한 문장으로 정리하면

내부함수에서 외부함수의 변수에 접근하는 경우, 
클로저가 생성되어서 외부함수의 스코프를 기억하기 때문에 변숫값을 기억하고 있다가
함수가 실행될 때마다 클로저가 기억한 값을 유지하게 된다.

 
 

자바 스크립트 아이콘 제작자: Freepik - Flaticon

출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

OpenAI ChatGPT (https://openai.com)