JavaScript:将参数传递给回调函数

vit*_*tto 271 javascript callback parameter-passing

我正在尝试将一些参数传递给用作回调的函数,我该怎么做?

function tryMe (param1, param2) {
    alert (param1 + " and " + param2);
}

function callbackTester (callback, param1, param2) {
    callback (param1, param2);
}

callbackTester (tryMe, "hello", "goodbye");
Run Code Online (Sandbox Code Playgroud)

Sim*_*rfe 241

如果你想要更通用的东西,你可以像这样使用arguments变量:

function tryMe (param1, param2) {
    alert(param1 + " and " + param2);
}

function callbackTester (callback) {
    callback (arguments[1], arguments[2]);
}

callbackTester (tryMe, "hello", "goodbye");
Run Code Online (Sandbox Code Playgroud)

但除此之外,您的示例工作正常(可以使用arguments [0]代替测试器中的回调)

  • 只要我们具有普遍性,`callback.apply(arguments)`作为`callbackTester`的函数体,可以在两个参数场景之外进行扩展. (51认同)
  • 仅供参考,使用匿名函数(Marimuthu的答案)或.bind()(Andy的答案)是将参数传递给回调的更简洁方法. (3认同)

Mar*_*amy 196

这也有效:

// callback function
function tryMe (param1, param2) { 
    alert (param1 + " and " + param2); 
} 

// callback executer 
function callbackTester (callback) { 
    callback(); 
} 

// test function
callbackTester (function() {
    tryMe("hello", "goodbye"); 
}); 
Run Code Online (Sandbox Code Playgroud)

另一种情景:

// callback function
function tryMe (param1, param2, param3) { 
    alert (param1 + " and " + param2 + " " + param3); 
} 

// callback executer 
function callbackTester (callback) { 
//this is the more obivous scenario as we use callback function
//only when we have some missing value
//get this data from ajax or compute
var extraParam = "this data was missing" ;

//call the callback when we have the data
    callback(extraParam); 
} 

// test function
callbackTester (function(k) {
    tryMe("hello", "goodbye", k); 
}); 
Run Code Online (Sandbox Code Playgroud)

  • +1.传递闭包/匿名函数是最好的方法. (23认同)
  • 这很好用,因为它还允许匿名函数传递如下参数:callbackTester(function(data){tryMe(data,"hello","goodbye");}); (2认同)

And*_*y E 57

你的问题不清楚.如果您正在询问如何以更简单的方式执行此操作,则应该查看ECMAScript第5版方法.bind(),它是Function.prototype的成员.使用它,你可以做这样的事情:

function tryMe (param1, param2) {
    alert (param1 + " and " + param2);
}

function callbackTester (callback) {
    callback();
}

callbackTester(tryMe.bind(null, "hello", "goodbye"));
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下代码,如果在当前浏览器中不可用,则添加该方法:

// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}
Run Code Online (Sandbox Code Playgroud)

bind() - PrototypeJS文档

  • @sje397:*arguments*不是\*real\*数组,因此它没有*slice()*方法.但是,*Array.prototype*上的*slice()*方法是故意通用的,因此您可以传递任何具有数字索引和*length*属性的对象,它将起作用. (7认同)
  • 这是最优雅的答案 (2认同)

Bla*_*lls 12

如果你有一个回调,它将被你的代码以外的其他东西调用,并且你想要传递额外的参数,你可以传递一个包装函数作为回调,并在包装​​器中传递额外的参数.

function login(accessedViaPopup) {
    //pass FB.login a call back function wrapper that will accept the
    //response param and then call my "real" callback with the additional param
    FB.login(function(response){
        fb_login_callback(response,accessedViaPopup);
    });
}

//handles respone from fb login call
function fb_login_callback(response, accessedViaPopup) {
    //do stuff
}
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您不确定要将多少个参数传递给回调函数。使用申请。

function tryMe (param1, param2) {
  alert (param1 + " and " + param2);
}

function callbackTester(callback,params){
    callback.apply(this,params);
}

callbackTester(tryMe,['hello','goodbye']);
Run Code Online (Sandbox Code Playgroud)


小智 5

在函数包装器中包装作为/带有参数传递的“子”函数,以防止在调用“父”函数时对它们进行评估。

function outcome(){
    return false;
}

function process(callbackSuccess, callbackFailure){
    if ( outcome() )
        callbackSuccess();
    else
        callbackFailure();
}

process(function(){alert("OKAY");},function(){alert("OOPS");})
Run Code Online (Sandbox Code Playgroud)


Ada*_*ski 5

来自具有任意数量参数和回调上下文的问题的代码:

function SomeFunction(name) {
    this.name = name;
}
function tryMe(param1, param2) {
    console.log(this.name + ":  " + param1 + " and " + param2);
}
function tryMeMore(param1, param2, param3) {
    console.log(this.name + ": " + param1 + " and " + param2 + " and even " + param3);
}
function callbackTester(callback, callbackContext) {
    callback.apply(callbackContext, Array.prototype.splice.call(arguments, 2));
}
callbackTester(tryMe, new SomeFunction("context1"), "hello", "goodbye");
callbackTester(tryMeMore, new SomeFunction("context2"), "hello", "goodbye", "hasta la vista");

// context1: hello and goodbye
// context2: hello and goodbye and even hasta la vista
Run Code Online (Sandbox Code Playgroud)


小智 5

使用柯里化函数,如这个简单示例所示。

const BTN = document.querySelector('button')
const RES = document.querySelector('p')

const changeText = newText => () => {
  RES.textContent = newText
}

BTN.addEventListener('click', changeText('Clicked!'))
Run Code Online (Sandbox Code Playgroud)
<button>ClickMe</button>
<p>Not clicked<p>
Run Code Online (Sandbox Code Playgroud)