Post

클로저(closure)에 대해 알아보자

안녕하세요 오늘은 클로저에 대해 이것저것 알아볼려고 합니다.

클로저

클로저(Closure)란 무엇인가?

클로저(closure)는 프로그래밍에서 중요한 개념으로, 함수와 그 함수가 선언될 때의 렉시컬 환경(lexical environment)을 함께 저장하는 구조입니다. 이 개념은 자바스크립트, 파이썬, 루비 등 여러 언어에서 중요한 역할을 합니다. 클로저를 이해하기 위해서는 함수, 변수의 범위(scope), 그리고 렉시컬 환경에 대한 이해가 필요합니다.

클로저의 기본 개념

  1. 함수와 렉시컬 환경: 함수는 자신이 정의된 시점의 변수들을 기억합니다. 이를 렉시컬 환경이라고 합니다.
  2. 클로저의 생성: 함수가 다른 함수 내부에서 정의되고, 그 내부 함수가 외부 함수의 변수에 접근할 수 있을 때 클로저가 생성됩니다.
  3. 변수의 캡처: 클로저는 외부 함수의 변수들을 ‘캡처’(capture)하여 함수가 호출될 때에도 그 변수들에 접근할 수 있도록 합니다.

클로저의 작동 원리

자바스크립트를 예로 들어 클로저의 작동 원리를 설명해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
function outerFunction() {
    let outerVariable = 'I am an outer variable';

    function innerFunction() {
        console.log(outerVariable); // outerVariable에 접근 가능
    }

    return innerFunction;
}

const closureFunction = outerFunction();
closureFunction(); // 'I am an outer variable' 출력

위 코드에서 outerFunctioninnerFunction을 반환합니다. 이때 innerFunctionouterFunction의 렉시컬 환경을 기억합니다. 따라서 outerFunction이 실행된 후에도 innerFunctionouterVariable에 접근할 수 있으며, 이를 클로저라고 합니다.

클로저의 특징

  • 상태 유지: 클로저를 이용하면 함수가 실행된 이후에도 변수의 상태를 유지할 수 있습니다. 예를 들어, 다음 코드를 살펴보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
function createCounter() {
    let count = 0;
    
    return function() {
        count++;
        return count;
    }
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

위 코드에서 createCounter 함수는 count 변수를 캡처하는 클로저를 반환합니다. 이 클로저는 count 변수를 유지하면서 호출될 때마다 값을 증가시킵니다.

  • 캡슐화: 클로저를 이용하면 외부에서 접근할 수 없는 변수를 클로저를 통해 접근할 수 있습니다. 이를 통해 데이터 은닉이 가능해집니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function createPerson(name) {
    return {
        getName: function() {
            return name;
        },
        setName: function(newName) {
            name = newName;
        }
    }
}

const person = createPerson('John');
console.log(person.getName()); // 'John'
person.setName('Doe');
console.log(person.getName()); // 'Doe'

위 코드에서 name 변수는 createPerson 함수 내에 캡슐화되어 직접 접근할 수 없지만, 클로저를 통해 접근하고 수정할 수 있습니다.

  • 콜백 함수: 클로저는 비동기적인 작업에서 유용하게 사용됩니다. 예를 들어, 이벤트 핸들러나 타이머 콜백 함수에서 클로저가 자주 사용됩니다.
1
2
3
4
5
6
7
function delayedGreeting(name) {
    setTimeout(function() {
        console.log('Hello, ' + name);
    }, 1000);
}

delayedGreeting('Alice'); // 1초 후 'Hello, Alice' 출력

위 코드에서 setTimeout 내의 함수는 클로저로, name 변수를 캡처하여 1초 후에도 name 변수에 접근할 수 있습니다.

클로저의 장단점

  • 장점: 클로저는 데이터 은닉과 상태 유지에 매우 유용합니다. 클로저를 사용하면 복잡한 상태를 관리하기 쉬워지며, 함수형 프로그래밍에서 중요한 역할을 합니다. 또한 클로저를 통해 모듈화된 코드를 작성할 수 있어 유지보수가 용이해집니다.

  • 단점: 클로저는 잘못 사용하면 메모리 누수를 유발할 수 있습니다. 클로저는 변수의 참조를 유지하기 때문에, 불필요한 메모리 사용이 발생할 수 있습니다. 또한 복잡한 클로저 구조는 디버깅을 어렵게 만들 수 있습니다.

결론

클로저는 프로그래밍에서 매우 유용하고 중요한 개념입니다. 함수와 변수의 관계를 깊이 이해하고, 이를 통해 복잡한 상태를 관리하고 데이터 은닉을 구현할 수 있습니다. 클로저를 잘 활용하면 코드의 가독성과 유지보수성을 높일 수 있으며, 다양한 프로그래밍 패턴을 구현할 수 있습니다. 클로저의 장점과 단점을 이해하고 적절히 활용하는 것이 중요합니다.

이렇게 클로저에 대해 알아보았습니다. 오늘도 필자의 글을 읽어주셔서 감사합니다.

This post is licensed under CC BY 4.0 by the author.