高阶函数 curry.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // fn(1)
  2. // fn(2)
  3. // fn(3)
  4. // fn(4)
  5. // fn(5)
  6. // fn()
  7. // console.log(1,2,3,4,5)
  8. function isFunction(fn) {
  9. return Object.prototype.toString.call(fn)=== '[object Function]';
  10. }
  11. let fn = _curry(console.log,'test');
  12. fn(1)
  13. fn(2)
  14. fn(3)
  15. fn(4)
  16. fn(5)
  17. fn()
  18. function _curry(fn){
  19. let _arguments = Array.from(arguments);
  20. let params = _arguments.splice(1);
  21. return function(){
  22. let __arguments = Array.from(arguments);
  23. if(__arguments.length >= 1){
  24. params.push(...__arguments);
  25. }else{
  26. return fn(...params,...arguments);
  27. }
  28. }
  29. }
  30. console.log('\n--------------------------------\n');
  31. /**
  32. * @returns {(function(): (*))|*}
  33. */
  34. function curry(){
  35. let _arguments = Array.from(arguments);
  36. let runLength = null;
  37. let fn = null;
  38. let params = [..._arguments];
  39. let cb = function (){
  40. let __arguments = Array.from(arguments);
  41. params.push(...__arguments);
  42. // 本次函数的参数
  43. // 历史函数的参数
  44. // 参数数量是否至少两个. 一般需要三个
  45. if(fn){
  46. // 空值执行
  47. if(__arguments.length<1 || (runLength && runLength <= params.length)){
  48. return fn(...params);
  49. }
  50. return cb;
  51. }
  52. // console.log(params);
  53. // 从输入中提取要执行的函数
  54. if(typeof params[0] === 'number' && isFunction(params[1])){
  55. runLength = params[0];
  56. fn = params[1];
  57. params = params.splice(2);
  58. }else if(isFunction(params[0])){
  59. runLength = null;
  60. fn = params[0];
  61. params = params.splice(1);
  62. if(fn.length){
  63. console.log(fn.length);
  64. runLength = fn.length;
  65. }
  66. }else if(typeof params[0] === 'number'){
  67. runLength = params[0];
  68. params = params.splice(1);
  69. }else{
  70. throw {message:'first param must function or number'}
  71. }
  72. // console.log(params);
  73. if(fn){
  74. if( runLength && runLength <= params.length){
  75. console.log('?');
  76. return fn(...params);
  77. }
  78. }
  79. return cb;
  80. }
  81. return cb;
  82. }
  83. function curry2(func) {
  84. return function curried(...args) {
  85. if (args.length >= func.length) {
  86. return func.apply(this, args);
  87. } else {
  88. return function(...args2) {
  89. return curried.apply(this, args.concat(args2));
  90. }
  91. }
  92. };
  93. }
  94. let c1 = function (event,msg){
  95. console.log(`event:${event} say ${msg}`)
  96. }
  97. let c2 = function (f1,f2,f3,f4){
  98. console.log(`1: ${f1}\n2: ${f2}\n3: ${f3}\n4: ${f4}`)
  99. }
  100. let c5 =function(){
  101. console.log(...arguments);
  102. }
  103. let fn1 = curry(c1,'test');
  104. let r1 = fn1('你好1');
  105. let r1_2 = fn1('你好2');
  106. let r1_3 = fn1('你好3');
  107. console.log('--------');
  108. let fn2 = curry(4);
  109. let r2 = fn2(c2)('a','b')('c','d');
  110. console.log('--------');
  111. let fn3 = curry(4,c2,'fn3 1','fn3 2');
  112. let r3 = fn3('tes')('你好','9999999');
  113. console.log('--------');
  114. let fn4 = curry(2,console.log);
  115. let r4 = fn4('fn4');
  116. console.log('--------');
  117. let fn5 = curry(c5);
  118. let r5 = fn5('text555')('你好---')();
  119. console.log('--------');