JavaScript - 같은 렉시컬 환경을 공유하는 클로저 함수 만들기

크리스·2023년 1월 4일
0
post-thumbnail

같은 렉시컬 환경을 공유하는 클로저 함수 만들기

자바스크립트 클로저를 공부하다가 인자로 함수를 받아 인자에 따라서 다른 기능의 함수를 반환하는 고차 함수 코드를 공부하게 되었다.
코드를 살펴보면

function makeCounter(predicate) {
  var counter = 0;
  return function () {
    counter = predicate(counter);
    return counter;
  };
}

function increase(n) {
  return ++n;
}
function decrease(n) {
  return --n;
}

const increaser = makeCounter(increase);
console.log(increaser()); // 1 출력
console.log(increaser()); // 2 출력 

const decreaser = makeCounter(decrease);
console.log(decreaser()); // -1 출력
console.log(decreaser()); // -2 출력 

위의 코드를 살펴보면 makeCounter 함수가 호출되면서 반환하는 함수는 자신이 생성되었을때의 렉시컬 환경을 기억하는 클로저 함수이다. 위에서는 increase, decrease 변수에 할당하면서 두번을 호출했다. 렉시컬 환경은 함수가 호출될때 각각의 렉시컬 환경을 생성한다. 결과적으로 변수에 할당된 함수는 독립적인 렉시컬 환경을 가지기 때문에 counter 변수를 공유하지 않는다.

그럼 렉시컬 환경을 공유하고 counter 값의 증가, 감소가 연동되도록 하기 위해서는 어떻게 해야할까?

결론적으로는 렉시컬 환경을 공유하는 클로저 함수를 만들어야 한다.

일단 해답을 보지 않고 나의 방식으로 코드를 변경해봤다.
해결 방법은 기존의 코드에서는 makeCounter 함수에서 increase, decrease 인자를 받아 이미 인자를 받아 클로저 함수를 반환할때 인자 값에 따라서 클로저 함수의 기능을 정하고 반환한다는 것이다. 같은 렉시컬 환경을 가지는 클로저 함수를 반환하기 위해서 어떤 보조함수를 사용할지는 클로저 함수를 반환받고 그 함수에 인수를 전달하여 기능을 바꿀수있는 방식으로 코드를 변경 하였다.

function makeCounter() {
  var counter = 0;
  return function (funcName) {
    counter = funcName(counter);
    return counter;
  };
}
function increase(n) { // 값 증가 함수
  return ++n;
}
function decrease(n) { // 값 감소 함수 
  return --n;
}

const hello = makeCounter();
console.log(hello(increase)); // 1
console.log(hello(increase)); // 2
console.log(hello(decrease)); // 1

hello 라는 변수에 할당 받은 클로저 함수를 내가 원하는 기능을 인수로 넣어주면 같은 counter 변수를 공유하는것을 볼수있다.

profile
재밌는건 다 합니다.

0개의 댓글