
자바스크립트의 클로저라는 개념을 정확히 이해하기 위해 쓰는 글
: 함수가 자신이 선언된 환경(스코프)를 기억하고, 그 환경에 접근할 수 있는 기능을 의미
흠 이렇게 봐서는 무슨 말인지 이해하기 쉽지 않다
더 알아보자
1. 함수와 외부 환경의 결합
: 함수 내부에서 선언된 변수가 외부 함수의 스코프에 접근할 수 있음
2. 상태 유지
: 외부 함수가 종료된 후에도 외부 함수의 변수를 클로저를 통해 계속 사용할 수 있음
3. 데이터 보호 (변수 은닉)
: 외부에서 직접 접근할 수 없는 변수를 은닉할 수 있음
아우 이렇게 봐서는 너무 복잡하고 알아듣기가 힘들다
예시 코드로 하나씩 살펴보자!
이 예시는 클로저의 조건을 만족하는 코드 예시와 같음

위의 코드를 살펴보면,
첫 번째 조건과 같이 함수 outerFunction이라는 함수 내에서 innerFunction이라는 함수를 정의한다.
그 다음 두 번째의 조건과 같게 innterFunction 함수 내에서 외부 함수인 outerFunction의 변수인 outerVariable에 접근한다.
이런 함수를 closureFunction이라는 변수에 outerFunction()으로 정의해준다.
그 다음 clousreFunction을 호출! 하면 outerFunction 내의 innerFunction 로직이 실행된다.
outerFunction의 return이 내부 함수명이기 때문에 outerFunction()으로 closureFunction 정의.
closureFunction()으로 호출하면 outerFunction 내의 innerFunction()이 호출되는 것이다.

이 예시에서는 내부 함수를 아예 익명 함수로 return에 넣어줬다.
여기서 상태 유지라는 말은 무슨 뜻일까?
: 외부 함수 counter가 실행된 후에도, 외부 함수의 변수인 count가 메모리에 남아있고 유지되는 것을 의미
(보통 함수의 로컬 변수는 함수 실행이 끝난 후 사라짐 -> 메모리에서 해제)

이 예시에서는 매개변수로 secret를 받았고,
return에 정의해준 익명 함수에서 secret를 return한다.
그 다음 createSecret함수를 인자와 함께 호출하여 getSecret이라는 변수에 할당했고,
getSecret을 호출함으로써 secret 값을 얻을 수 있다.
이렇게 함으로써, secret은 함수 내부에 선언된 로컬 변수이기에 외부에서 접근이 불가하다!
: secret 변수가 외부 코드에서 직접 접근되거나 수정할 수 없도록 은닉
외부에서 secret에 접근을 시도하려고 하면 아래와 같이 된다.

1. 데이터 은닉(Encapsulation)
: 외부에서 직접 접근할 수 없는 변수를 만들어 데이터를 안전하게 관리

2. 상태 유지(State Persistence)
: 함수 실행이 종료된 후에도 변수의 상태 기억
값이 초기화되지 않고, 이전 값이 유지되는 데이터 저장소처럼 동작

3. 모듈화 및 코드 재사용
: 관련된 데이터를 묶어 모듈화된 함수 생성 가능
: 중복 코드를 줄이고 재사용 가능한 코드 구조 설계 가능
위의 예시와 같이 반복적으로 작성할 수 있는 코드를 클로저로 묶어 재사용성을 높임!
4. 콜백 및 비동기 처리에 유용
: 이벤트 핸들러나 비동기 작업에서 상태를 저장하고 참조하는데 매우 유용함!

위 코드에서는 비동기 작업 중에서 isLoading이라는 상태를 유지하고 관리할 수 있다!
위의 코드만으로는 감이 잘 안온다 예시를 조금 더 확인해보자!
(1) 이벤트 핸들러에서의 클로저

: createButtonHandler 내의 clickCount는 각 버튼마다 독립적으로 상태 유지
(2) 비동기 작업에서의 클로저


이런식으로 내부 함수에서 재귀적으로 함수를 호출해 비동기 작업을 실행할 수도 있다!
간단히 React 안에서의 클로저 활용 예시 두 가지만 확인해보자!
1. React 컴포넌트에서 상태 캡슐화

위의 코드에서는 Counter라는 컴포넌트 함수에서 정의된 count와 setCount 상태가 있다.
이 함수 내에서 increment와 decrement라는 함수를 정의해 외부 함수의 변수인 setCount에 접근하여 사용하고 있다!
2. setTimeout 같은 비동기 작업에서 활용

DebouncedInput이라는 컴포넌트 함수 내에서 useEffect 내 함수를 정의 할 때 외부 변수인 value를 참조한다.
React 컴포넌트에서 상태와 관련된 함수들은 항상 클로저의 원리를 따른다.
클로저 덕분에 상태를 외부로부터 보호하고, 이벤트 핸들러와 같은 함수가 컴포넌트 내부 상태에 지속적으로 접근할 수 있다!