클로저는 함수와 함수가 선언된 어휘적(lexical)환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.
자바스크립트는 함수가 호출되는 환경과 별개로 기존에 선언되어 있던 환경, 즉 어휘적 환경을 기준으로 변수를 조회하려고 한다. 이와 같은 이유로 외부 함수의 변수에 접근할 수 있는 내부 함수를 클로저 함수라고 한다.
const adder = (x, y) => x + y;
adder(5, 7); // 12
// 함수의 호출(invocation)이 두 번 발생
const adder = x => y => x + y;
adder(5)(7); // 12
adder(5)의 리턴 값이 함수의 형태. 즉, adder는 함수를 리턴하는 함수이다.
typeof adder(5); // 'function'
adder(5) // y => x + y // (x = 5)
function 키워드 이용하면 다음과 같다
function adder = function(x) {
return function(y) { // 리턴값이 함수 형태
return x + y;
}
}
클로저는 리턴하는 함수에 의해 스코프(변수의 접근 범위)가 구분된다.
클로저의 핵심은 스코프를 이용해, 변수의 접근 범위를 닫는 (clouser; 폐쇄) 데에 있다.
따라서 함수를 리턴하는 것 만큼 변수가 선언된 곳이 중요하다.
const adder = function(x) { // 외부함수
return function(y){ // 내부함수
return x + y;
}
}
클로저 함수는 내부 함수는 외부 함수에 선언된 변수에 접근이 가능하다
외부 함수(adder)의 실행이 끝나더라도, 외부 함수 내 변수(x)를 사용할 수 있다.
const adder = function(x){
return function(y){
return x + y;
}
}
const add5 = adder(5); // 함수 실행이 끝나도, 5라는 값은 사용 가능
add5(7); // 12
add5(10); // 15
일반적인 함수는 함수 실행이 끝나고 나면 함수 내부의 변수를 사용할 수 없다,
반면에 클로저는 외부 함수의 실행이 끝나더라도, 외부 함수 내 변수가 메모리 상에 저장된다.(어휘적 환경을 메모리에 저장하기 때문)
cosnt tagMaker = tag => content => `<${tag}>${content}</${tag}>`
const divMaker = tagMaker('div');
divMaker('hello'); // <div>hello</div>
divMaker('codestates'); // <div>codestates</div>
cosnt anchorMaker = tagMaker('a');
anchorMaker('go'); // <a>go</a>
anchorMaker('urclass'); // <a>urclass</a>
클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 해준다.
const makeCounter = () => {
let value = 0;
return {
increase: () => {
value = value + 1;
},
decrease: () => {
value = value - 1;
},
getValue: () => value
}
}
const counter1 = makeCounter();
console.log(counter1()) // {increase : f, decrease, f, getValue f}
클로저를 이용해 객체에 대한 여러 개의 내부 함수를 리턴하도록 한다.
const counter1 = makeCounter();
counter1.increase(); // 1
counter1.increase(); // 2
counter1.decrease(); // 1
counter1.getValue(); // 1
const counter2 = makeCounter();
counter2.decrease(); // -1
counter2.decrease(); // -2
counter2.decrease(); // -3
counter2.getValue(); // -3
counter1 과 counter2의 value는 서로 영향을 끼치지 않는다
함수 재사용성을 극대화하여, 함수 하나를 완전히 독립적인 부품형태로 분리하는 것을 모듈화라고 한다.
클로저를 통해 데이터와 메서드를 같이 묶어서 다룰 수 있다.
즉, 클로저는 모듈화에 유리하다