Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何捕获函数中所需的参数数(curry函数部分应用程序)_Javascript_Design Patterns - Fatal编程技术网

Javascript 如何捕获函数中所需的参数数(curry函数部分应用程序)

Javascript 如何捕获函数中所需的参数数(curry函数部分应用程序),javascript,design-patterns,Javascript,Design Patterns,我正在处理curring函数和部分应用程序, 我正在尝试改进Schonfilize的功能: function schonfinkelize(fn){ var slice = Array.prototype.slice, stored_args = slice.call(arguments, 1); return function(){

我正在处理curring函数和部分应用程序, 我正在尝试改进Schonfilize的功能:

        function schonfinkelize(fn){
            var 
                slice = Array.prototype.slice,
                stored_args = slice.call(arguments, 1);
            return function(){
                var 
                    new_args = slice.call(arguments),
                    args = stored_args.concat(new_args);

                return fn.apply(null, args);
            }
        }
此函数允许作为参数传递函数
作为参数传递的函数的一部分(部分应用),因此第一次返回函数时,以及再次启动函数时,都会返回结果

function add(x, y, z){
    return x + y + z;
}

var val = schonfinkelize(add, 1, 2);

console.log( val(3) ) // console output--> 6
我想检查schonfilize函数“add”所需的参数数量(但它应该适用于每个函数),这样我就可以选择何时返回另一个函数或直接返回函数“add”的结果

因为如果我以这种方式使用Schonflize:

var val2 = schonfinkelize(add, 1, 2, 3);
console.log( val2 )    // --> function
console.log( val2() )  // --> 6
我必须启动函数两次,如果参数足够,我希望避免这种行为并直接定义值


一个可能的解决办法是:

        function schonfinkelize(fn){
            var 
                slice = Array.prototype.slice,
                stored_args = slice.call(arguments, 1);


                //* I have added this ********
                if(fn.apply(null, stored_args))
                    return fn.apply(null, stored_args);
                //****************************

            return function(){
                var 
                    new_args = slice.call(arguments),
                    args = stored_args.concat(new_args);

                return fn.apply(null, args);
            }
        }

可能是因为如果fn.apply(null,stored_args)返回的内容不是“null”或“NaN”,但我认为不是真正执行的,然后我希望使用参数。我认为没有正确的方法来确定任意函数的参数数。如果有必要,我更喜欢将
len
存储在函数中,并检查它是否已定义,如果已定义,并且如果
fn.len==stored_args.length
则返回只返回值的函数

function schonfinkelize(fn){
  var 
    slice = Array.prototype.slice,
    stored_args = slice.call(arguments, 1);

  if (fn.len != undefined && fn.len == stored_args.length) {
    var val = fn.apply(null, stored_args);

    return function () {
      return val;
    };
  }

  return function () {
    var 
      new_args = slice.call(arguments),
      args = stored_args.concat(new_args);

    return fn.apply(null, args);
  };
}

var f = function (a, b, c) {
  return a + b + c;
};

f.len = 3;

var g = schonfinkelize(f, 1, 2);
alert(g); // function () { var new_args = slice.call(arguments), args = stored_args.concat(new_args); return fn.apply(null, args); };
alert(g(3)); // 6

var g = schonfinkelize(f, 1, 2, 3);
alert(g); // function () { return val; };
alert(g()); // 6
function schonfinkelize(fn) {
    if (fn.length === arguments.length - 1)
        return fn.apply(this, [].slice.call(arguments, 1));

    var 
        slice = Array.prototype.slice,
        stored_args = slice.call(arguments, 1);
    return function(){
        var 
            new_args = slice.call(arguments),
            args = stored_args.concat(new_args);

        return fn.apply(null, args);
    }
}

只要您要求为传递的函数定义的参数反映最终接收的实际参数数量,就可以使用函数的
.length
属性将传递的参数与预期参数进行比较

function schonfinkelize(fn) {
    if (fn.length === arguments.length - 1)
        return fn.apply(this, [].slice.call(arguments, 1));

    var 
        slice = Array.prototype.slice,
        stored_args = slice.call(arguments, 1);
    return function(){
        var 
            new_args = slice.call(arguments),
            args = stored_args.concat(new_args);

        return fn.apply(null, args);
    }
}

旁注。。。如果将
fn
缓存在新变量中,并使用
此值覆盖第一个参数,然后使用
.call.apply()
,则可以避免使用
.slice()

    if (fn.length === arguments.length - 1) {
        var func = fn;
        arguments[0] = this;
        return func.call.apply(func, arguments);
    }

在严格模式浏览器中,您甚至可以避免使用make这个新变量,因为参数不再映射到
参数中的更改。但是,这在不支持严格模式的浏览器中不起作用。

我还想建议对代码进行个人改进,但我不得不说,由于斜视解决了问题,只需建议我使用属性.length。 在我看来,下一个级别是允许创建一个分部函数,可以在每次需要时调用,直到完成填充所有参数为止,我还简化了代码:

        function schonfinkelize(fn, stored_args){
            if(fn.length == stored_args.length)
                return fn.apply(null, stored_args);

            return function(){
                var 
                    new_args = arguments[0],
                    args = stored_args.concat(new_args);

                if(fn.length == args.length)
                    return fn.apply(null, args);

                return schonfinkelize(fn, args);
            }   
        }


        function add(x, y, w, z){
            return x + y + w + z;
        }


        var 
            val  = schonfinkelize(add, [1, 2, 3, 4]),
            val2 = schonfinkelize(add, [1, 2]),
            val3 = schonfinkelize(add, [1]);


        // checking
        console.log(val);           // output --> 10 // called only 1 time
        console.log(val2([3, 4]));  // output --> 10 // called in 2 times

        val3 = val3([2]);
        val3 = val3([3]);
        console.log(val3([4]));     // output --> 10 // called 4 times!

如果您可以假设传递的函数只需要定义为参数的参数,那么您可以使用函数的
.length
属性来确定有多少参数。因此,您的
add
函数将具有
add.length;//3
。因此,您可以将该数字与传递给返回函数的参数数量进行比较。我试图避免使用属性。length,因为它取所有传递参数的数量,所以可以是每个数量的数字,但如果我遵循您的推理,您是对的。我也曾想过使用适当的属性来附加到作用域,如v.len=3(如Speransky Danil的响应),但我希望找到函数的固有适当性,但在这一点上,我认为它不存在……函数的固有属性就是我在上面的评论中描述的。函数具有
.length
属性,该属性描述为该函数定义的参数数量。是的,一个人可以添加一个
.len
,但是为什么同一个人不简单地定义适当数量的参数呢?…在
schonlinkize()函数的顶部是这样的<代码>如果(fn.length-1==arguments.length)返回fn.apply(这是slice.call(arguments,1))