우리가 특정 함수에서만 컨트롤 되어야 하는 변수 special이 있다고 가정해보자.
let special = 0;
function specialHandle() {
special += 1;
}
console.log(special); // 0
specialHandle(); // special 컨트롤
console.log(special); // 1
위와 같이 컨트롤 할 수 있는데 만약 누군가가 실수로 인해 special값을 임의로 손대버리면 값이 변하게 되어버린다.
let special = 0;
function specialHandle() {
special += 1;
}
console.log(special); // 0
specialHandle(); // special 컨트롤
console.log(special); // 1
special = 100;
specialHandle();
console.log(special); // 101
물론 한두줄만 있는 코드라면 금방 찾을 수 있는데 여러명과 협업하게되고 코드의 줄 수 가 길어질수록 이러한 실수는 찾기 힘들어진다.
specialHandle로 수정할때를 제외하고 special변수를 접근 못하게하는 방법이 무엇이 있을까?
이때 사용하는게 closure이다.
Closure는 MDN문서를 보면 "주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합" 이라고 나와있다.
이렇게 보면 어려운 말이고 무슨 뜻인지 이해하기 힘든데 밑의 예시를 봐보자.
function closure() {
let special = 0;
function specialHandle() {
special += 1;
}
return {
specialHandle,
}
}
console.log(special); // special is not defined
const closureSpecial = closure();
console.log(closureSpecial); // {specialHandle : Function}
기존과 달리 special을 closure라는 함수안에서 선언함으로써 전역변수에서 지역변수가 된 걸 확인할 수 있다. 또한 closure함수에서 specialHandle을 리턴해줌으로써 closureSpecial에 specialHandle이라는 내부함수가 담김으로써 special을 컨트롤 할 수 있게되었다.
여기서 만약 내가 special을 출력하고싶으면 어떤방식을 사용해야할까? special은 지역변수기때문에 그냥 접근은 할 수 없고 특정한 방법을 사용해야한다.
function closure() {
let special = 0;
function specialHandle() {
special += 1;
}
function consoleSpecial() {
console.log(special);
}
return {
specialHandle,
consoleSpecial,
}
}
const closureSpecial = closure();
closureSpecial.consoleSpecial(); // 0
closureSpecial.specialHandle();
closureSpecial.consoleSpecial(); // 1
return을 똑바로 안해줄경우 아래와 같은 에러가 발생하게된다. 주의하자.
function closure() {
let special = 0;
function specialHandle() {
special += 1;
}
function consoleSpecial() {
console.log(special);
}
return {
specialHandle,
}
}
const closureSpecial = closure();
closureSpecial.consoleSpecial(); // closureSpecial.consoleSpecial() is not define
이런식으로 클로저 개념을 이용하여 함수를 이용해 지역변수로 선언해주면 특정 함수에서만 컨트롤 할 수 있는 나만의 변수가 만들어지게된다.