어제 공부한 클로저를 좀더 공부해봤다.
이걸 왜 공부해야 하는지, 어떤 상황에서 알아야 하는지를 생각하면서 최대한 맥락이 살아있고 간단한 설명을 스스로에게 계속 해봤다.
자바스크립트 클로저에 대한 실용적이고 쉬운 설명
클로저가 어려운 개념인 것도 맞지만 이걸 왜 써야 하는지를 몰라서 더 어렵게 느껴지는 부분도 있는 것 같다.
개인적으로 나는 클로저를 변수의 안전한 보관 방식이라고 이해했을 때 가장 명쾌했다.
비유를 하자면 일기장을 내가 아는 곳에 보관하는 것과 같다고 생각한다. 일기장을 방 아무데나 놓으면 누구든지 일기장을 볼 수 있고 수정할 수 있으니 곤란하니, 서랍에 넣어놓고 안전하게 보관하는 것이다.
변수도 마찬가지다. 그냥 변수를 어디서나 접근 가능하도록 보관하면 수정의 위험도 있고 하니, 서랍 같은 공간을 만들어 안전하게 보관해야 한다.
즉, 어디서나 접근 가능한 전역 변수로 두는 것이 아니라, 함수로 감싸주면서 외부에서 마음대로 접근할 수 없도록 지역 변수로 만들어주는 것이다.
함수가 일종의 서랍장 같은 역할을 한다고 이해하면 된다.
단, 그냥 함수만 띡 만들어놓으면 밖에서 열 수 없는 서랍장을 만들어놓은 것과 같다. 일기장을 안전하게 보관하긴 했는데 나조차도 그 일기장에 접근할 수 없게 되는 것이다.
그러니 서랍장 안에 있는 일기장에 접근할 수 있도록 함수도 마찬가지로 함수 안에 있는 변수에 접근할 수 있도록 코드를 추가적으로 작성해주어야 한다.
cnt 라는 변수가 있고, 이 변수를 cntPlus 라는 함수를 통해서만 1씩 증가하도록 만들어보자.
즉, cnt 라는 변수가 아무데서나 아무렇게나 수정되지 않고 오로지 cntPlus 라는 함수를 통해서 정해진 방식으로만 변하도록 하는 것이다.
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
console.log(cnt); //0
cntPlus();
console.log(cnt); //1
// cnt는 전역변수이기 때문에 중간에 cnt 를 바꿔버릴 수 있다.
cnt = 100;
cntPlus();
console.log(cnt); //101
위 코드에서는 cnt 가 전역 변수이고 어디에서나 접근이 가능한 상황이다.
중간에 cnt = 100 이라는 코드가 있으면 cnt 를 cntPlus() 로 1씩 증가하는 게 아니라 갑자기 100으로 바뀌어버릴 수도 있다.
그러므로 cnt 를 함수로 감싸서 아무데서나 접근할 수 없도록 만들어주어야 한다.
function closure() {
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
}
// cnt 와 cntPlus 둘다 closure 내부에서만 존재하기 때문에 함수 외부에서 참조할 수 없다.
console.log(cnt);
cntPlus();
cnt 와 cntPlus 를 위 코드처럼 closure 라는 함수로 감싸주었다.
밖에서 함부로 수정할 수 없기 때문에 보관은 잘 됐지만,
현재는 closure 내부에서만 사용할 수 있고 함수 외부에서는 참조할 수 없는 상태이다.
그러므로 함수 외부에서 접근할 수 있는 통로를 만들어주어야 한다.
function closure() {
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
return {
cntPlus,
}
}
//closure 함수의 반환값으로 cntPlus 함수를 담고 있는 객체가 반환되고, 이 값이 cntClosure에 담기게 된다.
const cntClosure = closure();
//객체에 담긴 함수를 실행시켜보자
cntClosure.cntPlus(); //cntPlus 함수에 따라 cnt는 1이 증가했을 것이다.
console.log(cnt); //그러나 cnt 를 출력해볼 수는 없다. 여기서는 closure의 지역 변수에 접근할 수 없기 때문이다.
closure가 cntPlus 함수를 담고 있는 객체를 반환하게끔 함수를 수정해주었다.
함수 외부에서도 cntPlus 함수를 실행시킬 수 있게 된 것이다.
그러나 cntPlus 로 cnt를 1씩 증가시킬 순 있지만, 외부에서 그 cnt를 출력해볼 수는 없다.
그러므로 closure 함수에 cnt를 출력해볼 수 있는 기능도 추가시켜주어야 한다.
function closure() {
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
//cnt를 출력하는 함수를 따로 만들어주었다
function printCnt() {
console.log(cnt);
}
return {
cntPlus,
printCnt,
}
}
const cntClosure = closure();
cntClosure.printCnt(); //cnt 값은 0 이므로 0이 찍힌다.
cntClosure.cntPlus(); //cntPlus 로 cnt를 1 증가시킨다.
cntClosure.printCnt(); //cnt 값은 1이 찍힌다.
closure 함수에 cnt를 출력해볼 수 있는 printCnt 함수를 추가해주었다.
외부에서 cnt 변수에 직접 접근할 수는 없지만,
closure 함수에서 정해놓은 방법에 맞게 함수를 사용하여 1씩 증가시키거나 값을 출력할 수 있게 된 것이다.
현재까지는 이렇게 2가지 함수를 통해서만 cnt 에 접근할 수 있다.
추가적인 기능을 추가하려면 위와 비슷한 방식으로 통로를 뚫어주는 느낌으로 함수를 추가해주면 된다.
cnt 를 원하는 값으로 바꾸는 기능을 추가해보자.
function closure() {
let cnt = 0;
function cntPlus() {
cnt = cnt + 1;
}
//cnt를 특정 값으로 바꿔주는 함수를 추가해주었다.
function setCnt(value) {
cnt = value;
}
function printCnt() {
console.log(cnt);
}
return {
cntPlus,
setCnt,
printCnt,
}
}
const cntClosure = closure();
cntClosure.printCnt(); //cnt 값은 0 이므로 0이 찍힌다.
cntClosure.cntPlus(); //cntPlus 로 cnt를 1 증가시킨다.
cntClosure.printCnt(); //cnt 값은 1이 찍힌다.
cntClosure.setCnt(100); //cnt 값은 100이 된다.
cntClosure.printCnt(); //cnt 값으로 100이 찍힌다.
원하는 값으로 cnt 를 바꿔주는 함수 setCnt 를 추가해주었고,
위 예시에서는 100으로 바꿔주고 출력하는 것까지 가능해졌다.
'기타' 카테고리의 다른 글
Nginx, PHP 연동 (1) - PHP-FPM (0) | 2021.12.23 |
---|---|
코드이그나이터 튜토리얼 - 뉴스 아이템 만들기 (0) | 2021.12.22 |
코드이그나이터 튜토리얼 - 정적 페이지, 뉴스 섹션 (0) | 2021.12.21 |
코드이그나이터 설치부터 php spark serve까지 (0) | 2021.12.21 |
자바스크립트에서 알아야 할 필수 개념들 (0) | 2021.11.03 |
댓글