클로저란?

클로저는 이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 함수입니다.
클로저는 여러 함수형 프로그래밍 언어에서 등장하는 보편적인 특성입니다.
자바스크립트 고유의 개념이 아닙니다.

 

구현

var outer = function () {
    var a = 1;
    var inner = function () {
        return ++a;
    }
    return inner;
}

var outer2 = outer();

console.log(outer2());
console.log(outer2());

위의 코드 결과를 보면 2와 3이 출력됩니다.
작성순서는 이렇습니다.
-outer 함수 구현
-outer2 선언
-console.log로 outer2 출력 (첫 번째)
-console.log로 outer2 출력 (두 번째)

 

하나씩 풀이해보면 처음 outer 함수를 보면 inner 함수 내부에서 외부변수인 a를 사용합니다.
그런데 outer 함수 결과는 inner 함수를 리턴하고 있습니다.
outer 함수의 실행 컨텍스트가 종료된 시점에는 a 변수를 참조하는 대상이 없어집니다.
하지만 참조 카운트가 0이 아니어서 가지비 컬렉터 대상이 아닙니다.
생명주기가 끝난 것으로 보이지만 외부에서 사용할 수 있습니다.
이렇게 이미 생명 주기상 끝난 외부 함수의 변수를 참조하는 것을 클로저라고 합니다.

 

로그 추가

위의 소스코드 중간마다 로그를 찍어보겠습니다.

console.log('========== 시작 ==========');

var outer = function () {
    var a = 1;
    console.log('a: ',a);
    var inner = function () {
        return ++a;
    }
    return inner;
}

console.log('A');
var outer2 = outer();

console.log('B');
console.log('a: ', outer2());

console.log('C');
console.log('a: ', outer2());

console.log('========== 종료 ==========');

 

로그A 밑에 outer2를 선언할 때 처음 outer 함수를 읽어옵니다.
a를 1로 선언했으니 로그에는 a의 값은 1입니다.

로그B 밑에 outer2를 콘솔로 출력할 때 outer 함수의 리턴 값인 inner를 실행시킵니다. 
inner 함수가 실행되어서 ++a가 결과인 2가 결과로 나옵니다.

로그C 밑에 outer2를 콘솔로 출력할 때 outer 함수의 리턴 값인 inner를 실행시킵니다.
inner 함수가 실행되어서 ++a가 결과인 3가 결과로 나옵니다.

 

클로저는 자바스크립트에만 사용되는 개념인가?

클로저는 자바스크립트 고유의 개념이 아닙니다.
함수형 프로그래밍 개념입니다.

 

후기

클로저를 공부하기 전에는 단순히 프론트앤드, 자바스크립트의 개념이라고 생각했는데 함수형 프로그래밍에 사용되는 개념이었습니다.
자바와 스프링에 대해 공부하다가 자바스크립트를 사용할 일이 생겨서 공부 중인데 결과적으로 자바와 스프링에도 도움이 되고있습니다.

Git: https://github.com/qkrcksrbs8/closure.git

+ Recent posts