외부함수보다 중첩함수의 생명주기가 길어서 외부함수가 종료된 시점에서도 식별자(변수)를 참조할 수 있는 중첩함수.
클로저는 자바스크립트의 고유 개념이 아닌, 함수형 프로그래밍 언어에서 사용되는 특성으로,
함수와 그 함수가 선언된 렉시컬 환경과의 조합
이라고 할 수 있다.
클로저는 이후에 좀 더 자세히 알아보도록 하고, 먼저 렉시컬 스코프부터 순차적으로 알아보도록 하겠다.
자바스크립트 엔진은 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는데, 이를 렉시컬 스코프라고 함
렉시컬 스코프는 정적 스코프
로,
함수를 어디에 정의했느냐에 따라 상위 스코프가 달라질 수 있음.
또한, 클래스가 없어도 생성자 함수와 프로토타입을 통해 객체지향 언어의 상속 구현이 가능하다는 특징이 있으며,
상위 스코프에 대한 참조는 함수 정의가 평가되는 시점에 함수가 정의된 위치에 의해 결정되는데,
이것이 렉시컬 스코프라 할 수 있다.
함수는 자신의 내부 슬롯 [[ Environment ]]에 자신이 정의된 환경(위치), 즉 '상위 스코프의 참조' 를 저장함.
함수가 정의된 위치와 호출되는 위치는 서로 다를 수 있으며,
렉시컬 스코프가 가능하기 위해서는 상위 스코프를 기억해야 한다.
이때, 함수는 자신의 내부 슬롯인 [[ Environment ]]
에 상위 스코프의 참조를 저장하게 된다.
함수 객체는 내부 슬롯 [[ Environment ]]
에 저장된 상위 스코프(렉시컬 환경의 참조)를 자신이 존재하는 동안 기억하게 된다.
맨 처음 언급한 내용과 같이 클로저는 외부함수보다 생명주기가 길며,
이미 종료된 외부함수를 참조하는 중첩함수를 클로저
라고 부른다 했다.
이때, 외부함수는 중첩함수의 내부 슬롯 [[ Enviroment ]]
에 외부함수의 렉시컬 환경
을 상위 스코프로서 저장하게 되며,
클로저
는 자연스레 함수와 해당 함수가 선언된 렉시컬 환경과의 조합이라고 볼 수 있다.
클로저는 상태를 안전하게 은닉하고 허용된 함수에게만 상태 변경을 할 수 있도록 하기 위해 사용한다.
예를 들어서,
개인 정보를 보호하는 캡슐화
나
고차 함수에서 콜백 함수로 사용되는 경우 등에서 클로저는 중요한 역할을 수행하게 되며,
외부에서 접근할 수 없는 변수를 만들어 데이터를 안전하게 은닉
하는것이 가능하게 되고
전역 스코프의 오염을 방지하여 예상치 못한 오류를 예방할 수 있게 된다.
캡슐화와 데이터의 은닉에 대한 내용은 아래에서 조금 더 자세하게 알아보자.
캡슐화
객체의 상태를 나타내는 프로퍼티
와 프로퍼티를 참조하고 조작하는 동작인 메서드
를 하나로 묶는 것을 이야기함.
정보 은닉
외부로부터 안전하게 보호해야 하는 데이터를 외부로 노출되지 않도록 감추는 것으로,
올바르지 않은 접근으로부터 객체의 상태 변경을 차단해 정보를 보호
하고, 객체 상호 의존성인 결합도
를 낮추는 효과가 있다.
자바스크립트는 기본적으로 public
, private
, protected
와 같은 접근 제한자를 제공하지 않는 프로그래밍 언어이며, 기본적으로 외부에서 참조가 가능한 public
한 상태이다.
따라서, 위에서 언급한 내용인 클로저
를 적극 활용하여 데이터를 보호하는 방법을 강구해볼 수 있겠다.