JavaScript

[JavaScript] 클로저 (Closure)

oagree0123 2021. 9. 8. 15:00

클로저는 스코프(Scope)에 대해 이해하고 있지 않으시다면, 클로저도 이해하시기 힘드실 것입니다. 이 글을 읽기전에 스코프에 대해 공부하시고 오시는 것을 추천 드립니다. : )

 

1. 클로저

MDN에서는 "클로저는 함수와 함수가 선언된 어휘적 환경(lexical scope) 의 조합이다."라고 정의하고 있습니다. 조금 풀어서 설명하자면, 클로저는 외부 함수의 실행이 끝나 함수가 소멸되어도 내부 함수가 외부 함수의 변수에 접근할 수 있는 것을 말합니다. 역시 글로만 설명하니 무슨 이야기인지 정확하게 이해하기 힘듭니다. 설명을 위해 아래의 코드를 보겠습니다.

function ex() {
    var id = '01';
    
    function inner() {
        console.log(id);
    }
    return inner;
}

var check = ex();
check(); // 01

위 코드에서 ex() 함수가 리턴되어 사라진 후에 내부 함수 inner()가 생성되었는데, 내부 함수에서 외부 함수의 지역 변수에 접근한 것을 볼 수 있습니다. 이처럼 외부 함수가 사라지지 않고 내부 함수의 참조를 위해 값이 유지되는 것을 클로저라고 합니다.

 

조금 더 자세하게 보겠습니다. 먼저 ex()를 출력한 결과가 무엇일까요?

console.log(ex());

//결과
ƒ inner() {
        console.log(id);
}

ex() 함수는 inner 함수를 return 하고 있습니다. 또한, 변수 check는 반환된 ex() 함수를 참조하고 있습니다. 일반적으로 함수 내부의 지역 변수는 함수의 실행이 종료되면 파기되는데, 클로저 함수에 의해 참조되는 경우에는 지역 변수를 파기하지 않고 계속 보관하고 있는 것입니다. 따라서, innder() 함수에는 변수 id가 없기 때문에 에러가 날 것이라고 생각되었지만 클로저에 의해 실행되는 것을 알 수 있습니다.

 

2. 함수의 캡슐화(은닉화)

클로저를 이용하면 함수의 변수를 외부에서 함부로 바꿀 수 없는 private한 변수로 만들 수 있습니다.

function user(name) {
    return {
        setName: function(_name) {
            name = _name;
        },
        getName: function() {
            return name;
        }
    }
}

var Kim = user("Kim");
var Lee = user("Lee");

Lee.setName("Park");

console.log(Kim.getName());
console.log(Lee.getName());

위 코드처럼 클로저를 사용하면 name을 변경하는 기능을 만들지 않는 이상, 외부에서 name을 변경할 수 없습니다.