본문 바로가기
JavaScript

클로저 활용 예시 (2)

by whoyoung90 2022. 5. 1.
반응형

클로저 활용 예시 (2) - 부분 적용 함수

 

부분 적용 함수란

a개의 인자를 받는 함수에 미리 b개의 인자만 넘겨 기억시켰다가,

나중에 (a - b)개의 인자를 넘기면 비로소 원래 함수의 실행 결과를 얻을 수 있도록 만든 함수이다.

 

부분 적용 함수가 클로저의 활용 예시인 이유는

미리 일부 인자를 넘겨두어 기억하게끔 하고

추후 필요한 시점에 기억했던 인자들까지 함께 실행하게 한다는 원리가 클로저의 정의와 부합하기 때문이다.

 

/* 고차함수를 활용한 부분 적용 함수 */

let partial = function() { // 🅰️ console.log(arguments);
  let originPartialArgs = arguments;
  let func = originPartialArgs[0];
  if (typeof func !== 'function') {
    throw new Error('첫 번째 인자가 함수가 아님');
  }

  return function() { // 🅱️ console.log(arguments);
   /* [ A함수 arguments ] */
   let partialArgs = Array.prototype.slice.call(originPartialArgs, 1); // [ 1, 2, 3, 4, 5 ]
   /* [ B함수 arguments ] */
   let restArgs = Array.prototype.slice.call(arguments); // [ 6, 7, 8, 9, 10 ]
    
   return func.apply(this, partialArgs.concat(restArgs)); // 55
   // func가 결국 add함수니까 func.apply(this, [array]) => add함수에 의해 [array]의 합계 리턴
  };
};

let add = function() { // ✅ console.log(arguments);
  let result = 0;
  for (let i = 0; i < arguments.length; i++) {
   result += arguments[i];
  }
  return result;
};

let addPartial = partial(add, 1, 2, 3, 4, 5);
console.log(addPartial(6, 7, 8, 9, 10));

partialArgs은 🅰️함수의 arguments를 배열화하였고 slice.call(originPartialArgs, 1)

restArgs는 🅱️함수의 arguments를 배열화하였다. slice.call(arguments)

 

 

함수를 리턴하는 함수인 고차함수를 활용하였는데,

처음의 🅰️ 함수와, 함수안의 함수 🅱️arguments값이 다른 것을 주목할 필요가 있다.

/* 🅰️ partial함수의 console.log(arguments) */
{
  '0': ƒ add(), '1': 1, '2': 2, '3': 3, '4': 4, '5': 5,
  length: 6,
  callee: ƒ partial(),
  __proto__: {...}
}

/* 🅱️ 익명함수의 console.log(arguments) */
{
  '0': 6, '1': 7, '2': 8, '3': 9, '4': 10,
  length: 5,
  callee: ƒ (),
  __proto__: {...}
}


/* ✅ add함수의 console.log(arguments) */
{
  '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, '8': 9, '9': 10,
  length: 10,
  callee: ƒ add(),
  __proto__: {...}
}

 

 

반응형

'JavaScript' 카테고리의 다른 글

프로토타입(prototype)  (0) 2022.05.22
커링 함수  (0) 2022.05.21
클로저 활용 예시 (1)  (0) 2022.03.31
setInterval과 addEventListener  (0) 2022.03.31
클로저 (Closure)  (0) 2022.03.30

댓글