JS - 클로저 (Closure)

이지호_tech 2024. 4. 24. 13:38

 

클로저(Closure) 란 

1. 함수와 그 함수가 선언된 렉시컬 환경의 조합

2. 다른 곳으로 넘긴 함수 내에서 외부 변수를 사용하는 경우 , 해당 변수는 어딘가에 접근해야 하므로 js에서는 함수를 프로그램 내 어디에서 실행했는지와는 상관없이 함수를 정의할 때 결정된 스코프를 유지하는 것

 

이 클로저의 특징은 함수가 자신이 생성될 때의 렉시컬 환경을 "기억한다" 는 함수라는 것이다.

그러므로 외부 함수가 종료된 후에도 외부 함수의 변수에 접근 할 수 있다.

 

주로 비동기 처리 , 데이터 캡슐화 , 고차 함수 콜백등의 상황에서 사용된다.

 

function createGreeting(greeting) {
    return function(name) {
        console.log(greeting + ', ' + name + '!');
    };
}

const greetHello = createGreeting('Hello');
greetHello('John'); // 출력: "Hello, John!"

const greetHi = createGreeting('Hi');
greetHi('Jane'); // 출력: "Hi, Jane!"

 

createGreeting 함수는 문자열 greeting을 인자로 받고, 내부에 또 다른 함수를 정의하여 반환한다. 

반환된 함수는 createGreeting 함수의 greeting 변수에 접근할 수 있다. 여기서 반환된 함수가 클로저이다. 

greetHello와 greetHi는 각각 다른 greeting 값을 기억하는 클로저이다.

 

function fetchData(userId) {
    const url = `https://api.example.com/users/${userId}`;

    // 비동기 API 호출
    fetch(url)
        .then(response => response.json())
        .then(data => {
            console.log(`User Name: ${data.name}`);
            // 클로저를 통해 `userId`와 `url`에 접근 가능
            console.log(`Fetched data for userId: ${userId} from URL: ${url}`);
        })
        .catch(error => console.error('Fetching error:', error));
}

fetchData(1); // User Name: John Doe
              // Fetched data for userId: 1 from URL: https://api.example.com/users/1

 

여기서 클로저는 fetchData 함수 내부에서 비동기 호출(fetch)의 콜백 함수 내에서 사용된다. 콜백 함수는 fetchData 함수의 지역 변수인 userId와 url에 접근할 수 있다. 이는 콜백 함수가 외부 함수(fetchData)의 스코프에 있는 변수를 "기억"하기 때문이다.

비동기 호출이 완료되어 콜백 함수가 실행될 때, userId와 url 변수는 이미 fetchData 함수의 실행이 완료된 후지만, 콜백 함수는 이 변수들에 여전히 접근할 수 있습니다. 이러한 특성은 클로저 덕분에 가능하다. 클로저는 함수가 선언될 때의 렉시컬 환경을 기억하므로, 해당 함수가 나중에 실행될 때도 그 환경에 접근할 수 있게 해준다.

클로저를 사용함으로써, 각각의 함수 호출이 실행될 때마다 해당 환경을 "기억"하는 독립적인 환경을 생성할 수 있다. 이는 프로그래밍에서 매우 강력한 도구로, 함수형 프로그래밍 패러다임에서 중요한 역할을 하게된다.

 

전 포스트의 스코프에서 설명했던 POLP는 클로저에서도 기반이 된다.

 

변수를 오랫동안 유지하는 경우 , 클로저를 사용하면 변수를 외부 스코프에 두는 대신 더 제한된 스코프로 캡슐화할 수 있다.
이렇게 하면 함수 내부에서 함수 밖 해당 변수에 계속 접근할 수 있어 변수를 더 넓은 범위에서 사용할 수 있다.

클로저는 함수에서만 일어나는 함수의 동작이다.
함수를 호출하고, 그 호출된 함수가 해당 함수를 정의한 스코프 체인이 아닌 다른 분기에서 호출되어야 한다.

 

내부 함수가 외부 스코프에 있는 변수를 참조하는 것 == 클로저

 

클로저의 핵심은
1. 반드시 함수와 관련되어야 한다.
2. 외부 스코프의 변수를 적어도 하나 이상 참조해야 한다.
3. 참조하려는 변수가 있는 스코프 체인의 다른 분기에서 함수를 호출해야 한다.

이렇게 세가지로 정리할 수 있다.


또한 변수에 대한 클로저가 사라지면 변수는 가비지 컬렉션 처리 된다.
이런 클로저의 특성은 변수의 GC를 예기치 않게 막아 메모리 사용을 급증 시키는 요인이 될 수 있어서 필요없어진 클로저는 제때 삭제하는게 중요하다.

'' 카테고리의 다른 글

Next js Lottie 사용할때 Document is not defined Build 에러  (0) 2024.06.26
Mock Service Worker  (0) 2024.05.23
JS - 스코프(Scope)  (0) 2024.04.24
Babel 이란? +babel-plugin-macros  (1) 2024.04.19
Javascript 의 객체 리터럴 / 관련 팁 들  (0) 2024.04.16