传递一组参数

时间:2012-06-08 17:34:02

标签: javascript functional-programming

我试图拥有一个传递函数的函数,并使用一组args调用它。例如:

function foo(func, args) {
  return func(args);
}

但是,我不知道args中可能有多少个元素,而func应该能够成为任意数量args的任意函数。我该如何处理?

另外说我想存储传递给foo的函数,只有在之前没有调用它们时才调用它们。

我可以这样做:

var calledFuncs = [];
function foo(func, args) {
  if(calledFuncs.indexOf(func) === -1) {
    calledFuncs.push(func);
    return func(args);
  }
}

谢谢,我对JavaScript中的函数式编程有点新鲜。

3 个答案:

答案 0 :(得分:8)

您正在寻找func.apply

  • 第一个参数是上下文属性this值。你不想改变它,所以传递它。
  • 第二个参数是一个包含参数的数组,当然可以是动态长度。

所以你可以这样做:

return func.apply(this, args);

您似乎对第二个问题有了很好的解决方法(替换了func(args))。但是,您可能希望存储被调用函数的返回值,因为foo现在为除第一个以外的任何调用返回undefined

答案 1 :(得分:2)

使用apply

func.apply(this, args);

apply将一组参数作为第二个参数。

apply的第一个参数将是您正在调用的函数范围内的this的值。因此,您可以传递当前的this或其他任何您想要的内容。

就你的第二个问题而言,这只适用于命名函数。您可以使用func.name将函数名称存储在数组中:

var calledFuncs = [];
function foo(func, args) {
   if(calledFuncs.indexOf(func.name) === -1) {
      calledFuncs.push(func.name);
      return func(args);
   }
}

这对匿名函数不起作用,对IE或Opera中的命名函数不起作用。你将不得不解析它,也许是这样:

var name = func.toString().replace(/\n/g, "").replace(/\s*\(.*$/, "").replace(/^\s*function\s+/, "");

就你的第二个问题而言,你可以做你现在正在做的事情。但我不认为它适用于以下情况:

foo(function() {
}, []);

foo(function() {
}, []);

它会调用这两个函数。

答案 2 :(得分:1)

您想要Function.prototype.apply

func.apply(this,args);

将上下文(第一个参数)设置为您想要的任何内容,包括null以获取window全局(就像您当前的func(...)调用一样。

虽然与您的问题没有直接关系,但请参阅相关的Function.prototype.call方法,该方法允许您类似地设置上下文,但传递显式参数。