函数使用多个参数调用2种方法

时间:2015-08-05 14:02:54

标签: javascript

我们大多数人都知道我们可以创建一个这样的简单函数。

function calc(a,b){
   return a+b
}
calc(1,1); //returns 2

我们也可以做这样的事情

function calc(a){
    return function(b){
      return a+b
    }
}
calc(1)(1); //returns 2

如果我们有多个参数呢?

function calc() {
    function r(arg) {
        var a = [];
        for(var i = 0, l = arg.length; i < l; i++){
            a[i] = arg[i];
        }

        return a.reduce(function(p, c) {
          return p + c;
        });

    }
    var res = r(arguments);
    return function() {
        res += r(arguments);
        return res;
    }
}

适用于calc(1,2)(1),但不适用于calc(1,2,1)

有没有办法合并两个版本? 这意味着在打电话时 calc(1,1)我们也可以致电calc(1)(1),两者仍然会返回2.

calc(1,2,3) calc(1,2)(3) calc(1)(2,3)全部返回6

4 个答案:

答案 0 :(得分:1)

之后需要知道要进行计算的参数数量; - )

你可以创建一个将事物转化为这种功能的函数 像这样的东西:

function curry(f){
  var args = [];
  return addargs;
  function addargs(){
    args=args.concat([].slice.call(arguments));
    return args.length<f.length? addargs.bind(this) : f.apply(this,args);
  }
}

然后你可以这样做:

var calc = curry(function(a,b,c){return a+b+c});
calc(1,2)(3); // = 6

但你不能让它采用可变数量的参数来讨论那些 - 它不知道何时返回答案

答案 1 :(得分:1)

所以这是我最接近我的问题。 使用下面的代码,如果我在函数前面添加一个+号,它就可以工作 所以+calc(1,2,3) +calc(1,2)(3) +calc(1)(2)(3) +calc(1,2)(1)(3,0,1)将全部运作

function calc(){
    var args = [].map.call(arguments, function(a) {
        return a;
    });
    var recursiveSum = function(arr) {
        return +arr.reduce(function(a, b) {
            return +a + (b && b.reduce ? recursiveSum(b) : +(isNaN(b) ? 0 : b));
        }, 0);
    };
    calc.__proto__.valueOf = function() {
        return recursiveSum(args);
    };
    return calc.bind(this, args);
}

答案 2 :(得分:0)

  

如果有可能以某种方式做这样的事情。 calc(无限args)(无限args)=一些结果

这可能是我能想象到的最接近你想要的东西:

function calc(a,b) {                     // we expect a and b to be arrays
    if (Array.isArray(a)) {              // check if a is an array
        if (b === undefined) {           // if we don't have a b
            return calc.bind(null, a);   // return a curried function
        }
        if (!Array.isArray(b)) {         // if b isn't an array
            return calc(a, [].splice.call(arguments,1));    // turn all the arguments 
                                                            // after a into an array and 
                                                            // call the function again
        }
        // if both a and b are arrays, just calculate the sum and return it
        var aSum = a.reduce(function(p,c) { return p + c },0);
        return b.reduce(function(p,c) { return p + c}, aSum);
    }
    // if a was not an array, turn the arguments into an array and call again
    return calc([].splice.call(arguments,0));
}

console.log(calc(1,2)(null));      // 3
console.log(calc(1,2)(3,4));       // 10
console.log(calc(1)(3,4));         // 8
console.log(calc(1,2,3)(null));    // 6

这里的限制是无法执行calc(1,2)因为它返回一个函数,所以如果你想要结果,唯一的方法是调用它并传递null

这里的想法是我们有一个函数,它将采用两个数组ab并将它们加在一起。如果a不是数组,我们将获取所有传递的参数并将其转换为数组,然后再次调用该函数将该数组作为a传递。

如果a是,而数组和b未定义,那么我们将返回一个使用a的函数。如果a是一个数组且b不是数组,那么我们将所有参数(a除外)转换为数组并再次调用该函数。如果b是一个数组,那么我们只是进行计算并返回结果。

答案 3 :(得分:-1)

又一种方式

function sum() {
  function add(a, b) {
    return a + b;
  };

  var num = [].reduce.call(arguments, add);

  function inner() {
    return sum.apply(this, [].concat.apply([num], arguments));
  }
  inner.toString = inner.valueOf = inner.toJSON = function() {
    return num;
  }
  return inner;
}

function o(prepend, val){
  document.getElementById('res').innerHTML += (prepend? (prepend+": "):"")+(typeof val == 'string'? val : JSON.stringify(val)) + '<br />';
}

o('sum(1,2,3)(4,5,6)(7)',sum(1,2,3)(4,5,6)(7));
o('sum(1,2,3)',sum(1,2,3));
o('sum(1)(2,3)', sum(1)(2,3));
o('sum(1,2)(3)',sum(1,2)(3));
o('sum(1,2)(3)+"4"',sum(1,2)(3)+"4");
o('sum(1)(2,3)+4',sum(1)(2,3)+4); //10
<div id="res"></div>