javascript中是否有一种方法可以调用具有未知数量参数的回调?
例如,如果这是我们的调用方法:
function invokeCallback(callback, params) {
return callback.invoke(params);
}
如果这些是我们的示例回调方法:
function action() {
doSomeAction();
}
function greet(msg) {
console.log(msg);
}
function nameage(name, age) {
var msg = 'My name is ' + name + ' and my age is ' + age;
console.log(msg);
}
如果我们可以轻易地这样称呼它们:
invokeCallback(action);
invokeCallback(greet, 'Hello!');
invokeCallback(nameage, 'Bob', 20);
然后会很棒。
这样的事情可能吗?
答案 0 :(得分:6)
正如其他答案中已经提到的,Function.prototype.apply和Function.prototype.call是您要查看的两种方法。它们的操作方式略有不同 - apply将参数作为单个数组,而call将它们作为单独的参数。
您可能希望探索使用此技术的相关概念是currying。
关于您的示例,您应该考虑从函数定义中删除params
参数并消除作为回调函数本身的开放参数:
function invokeCallback(callback) {
var params = Array.prototype.slice.call(arguments, 1);
return callback.apply(this, params);
}
答案 1 :(得分:3)
是的,这是可能的。关键功能是Function#apply
,它在提供上下文和参数时调用函数。参数以数组形式给出。 (以这种方式,它与Function#call
不同,其中参数是明确给出的。)
那么让我们来看看你的函数签名:
function invokeCallback(callback, params) {
我们可以非常简单地做到这一点:
function invokeCallback(callback, params) {
return callback.apply(null, params);
}
(第一个参数是函数的 context ,即其中this
的值。由于我们不想指定任何特定的东西,我们使用{{1} }。)
但是,您调用函数的方式略有不同:
null
你看到了区别吗?这里,参数是明确给出的,而不是数组。因此,我们需要略微区别对待它。在函数内,arguments
对象包含提供给函数的参数。在上述情况下,它将包含三个:invokeCallback(nameage, 'Bob', 20);
,nameage
和'Bob'
。我们希望使用参数20
和nameage
来调用'Bob'
。
20
对象看起来像一个数组,但它不是一个。因此,我们必须使用稍微复杂的Array#slice
函数调用来获取值:
arguments
所以我们的功能看起来像这样:
var params = Array.prototype.slice.call(arguments, 1); // get all arguments after the first one
答案 2 :(得分:2)
callback.apply或callback.call
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
您的回调将如下所示:
function invokeCallback(callback, params) {
return callback.apply(this,params);
}