我试图拥有一个传递函数的函数,并使用一组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中的函数式编程有点新鲜。
答案 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)
func.apply(this,args);
将上下文(第一个参数)设置为您想要的任何内容,包括null
以获取window
全局(就像您当前的func(...)
调用一样。
虽然与您的问题没有直接关系,但请参阅相关的Function.prototype.call
方法,该方法允许您类似地设置上下文,但传递显式参数。