자바스크립트의 클로저 정확히 이해하기

제이미·2024년 12월 9일
0

자바스크립트

목록 보기
10/14
post-thumbnail

자바스크립트의 클로저라는 개념을 정확히 이해하기 위해 쓰는 글

클로저(Closure)란?

: 함수가 자신이 선언된 환경(스코프)를 기억하고, 그 환경에 접근할 수 있는 기능을 의미

흠 이렇게 봐서는 무슨 말인지 이해하기 쉽지 않다
더 알아보자

클로저의 특징으로는 크게 3가지가 있다

1. 함수와 외부 환경의 결합
: 함수 내부에서 선언된 변수가 외부 함수의 스코프에 접근할 수 있음

2. 상태 유지
: 외부 함수가 종료된 후에도 외부 함수의 변수를 클로저를 통해 계속 사용할 수 있음

3. 데이터 보호 (변수 은닉)
: 외부에서 직접 접근할 수 없는 변수를 은닉할 수 있음

클로저를 만들 때 아래 두 가지 조건을 만족해야 한다!

  1. 함수 내부에서 또 다른 함수 정의
  2. 그 내부 함수가 외부 함수의 변수에 접근

아우 이렇게 봐서는 너무 복잡하고 알아듣기가 힘들다
예시 코드로 하나씩 살펴보자!

클로저의 특징 첫 번째 특징(함수와 외부 환경의 결합)부터 살펴보자

이 예시는 클로저의 조건을 만족하는 코드 예시와 같음

위의 코드를 살펴보면,
첫 번째 조건과 같이 함수 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에 접근을 시도하려고 하면 아래와 같이 된다.

클로저의 장점이 뭘까? 크게 4가지로 확인해보자.

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

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

3. 모듈화 및 코드 재사용
: 관련된 데이터를 묶어 모듈화된 함수 생성 가능
: 중복 코드를 줄이고 재사용 가능한 코드 구조 설계 가능
위의 예시와 같이 반복적으로 작성할 수 있는 코드를 클로저로 묶어 재사용성을 높임!

4. 콜백 및 비동기 처리에 유용
: 이벤트 핸들러나 비동기 작업에서 상태를 저장하고 참조하는데 매우 유용함!

위 코드에서는 비동기 작업 중에서 isLoading이라는 상태를 유지하고 관리할 수 있다!

위의 코드만으로는 감이 잘 안온다 예시를 조금 더 확인해보자!

(1) 이벤트 핸들러에서의 클로저

: createButtonHandler 내의 clickCount는 각 버튼마다 독립적으로 상태 유지

(2) 비동기 작업에서의 클로저

이런식으로 내부 함수에서 재귀적으로 함수를 호출해 비동기 작업을 실행할 수도 있다!

그렇다면 클로저를 실제 React 프로젝트에서 어떻게 사용될까?

간단히 React 안에서의 클로저 활용 예시 두 가지만 확인해보자!

1. React 컴포넌트에서 상태 캡슐화

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

2. setTimeout 같은 비동기 작업에서 활용

DebouncedInput이라는 컴포넌트 함수 내에서 useEffect 내 함수를 정의 할 때 외부 변수인 value를 참조한다.

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

profile
프론트엔드 개발하다 궁금할 때

0개의 댓글