Javascript:将自定义参数传递给回调函数

Posted

技术标签:

【中文标题】Javascript:将自定义参数传递给回调函数【英文标题】:Javascript: Passing custom arguments to a callback function 【发布时间】:2011-07-05 21:18:35 【问题描述】:

我有这个回调函数设置:

var contextMenu = [];
var context = [  "name": "name1", "url": "url1" , "name": name2", "url: "url2"  ];
for(var i=0; i < context.length; i++) 
    var c = context[i];
    var arr = ;
    arr[c.name] = function()  callback(c.url); 
    contextMenu.push( arr );

function callback(url) 
   alert(url);

问题在于传递给回调的 url 值始终是上下文变量中的最后一个值——在本例中为“url2”。我期望将特定的值传递给回调的每个“实例”,但由于回调似乎记住了相同的值,因此上次引用它。

我有点卡住了。任何帮助将不胜感激。

PS:我正在使用jQuery ContextMenu,据我了解,它不支持将自定义数据发送到其回调函数。正是在这种情况下,我遇到了这个问题。在这种环境下要克服的任何建议也很有帮助!

【问题讨论】:

this post 和其他几十个的可能重复 【参考方案1】:

使用额外的闭包。

arr[c.name] = (function(url)  
    return function()  callback(url); 
)(c.url);

请参阅Creating closures in loops: A common mistake 和大多数其他questions 关于此主题,现在您的问题也已添加到此池中。

【讨论】:

谢谢!我多次被“关闭”迷惑,现在有了一些实践经验,它变得更加清晰! 闭包非常棒,尤其是因为函数是 javascript 中的一等对象,没有闭包就很难做到。想象一下,将函数中引用的每个变量都作为参数传递——在这种情况下,callbackurl 以及参数是通过值传递还是通过引用传递的所有令人头疼的问题。 我认为值得注意的是,并不是闭包本身使它工作,而是更具体地说,这个闭包代码包括传递一个参数——这使得按值传递代替引用保留在原始闭包中,从而克服了原始问题。我认为这使解释更加完整。【参考方案2】:

你在 for 循环中创建了一系列闭包函数

arr[c.name] = function()  callback(c.url); 

并且它们都共享相同的范围,因此相同的 c 对象将在循环结束后指向数组中的最后一个元素。

要解决此问题,请尝试这样做:

arr[c.name] = function(url) 
    return function()  callback(url); ;
(c.url);

在此处阅读有关关闭的更多信息:http://jibbering.com/faq/notes/closures/

【讨论】:

【参考方案3】:

一般解决方案

回调创建者助手

我沿着Anurag 指出的in his answer 的Creating closures in loops: A common mistake 创建了一个通用回调创建器。

回调创建者参数

函数的第一个参数是回调。 其他所有参数都将作为参数传递给此回调。

传递的回调参数

参数的第一部分来自您传递给回调创建器助手的参数(在我之前描述的第一个参数之后)。 第二部分来自调用者将直接传递给回调的参数。

源代码

//Creates an anonymus function that will call the first parameter of
//this callbackCreator function (the passed callback)
//whose arguments will be this callbackCreator function's remaining parameters
//followed by the arguments passed to the anonymus function
//(the returned callback).
function callbackCreator() 
    var functionToCall = arguments[0];
    var argumentsOfFunctionToCall = Array.prototype.slice.apply(arguments, [1]);
    return function () 
        var argumentsOfCallback = Array.prototype.slice.apply(arguments, [0]);
        functionToCall.apply(this, argumentsOfFunctionToCall.concat(argumentsOfCallback));
    

示例用法

这是一个自定义的 AJAX 配置对象,它的成功回调使用我的回调创建者助手。使用响应文本,回调根据操作发生的行更新DataTables 表中行的第一个单元格,并打印一条消息。


    url: 'example.com/data/' + elementId + '/generate-id',
    method: 'POST',
    successHandler: callbackCreator(function (row, message, response) //Callback parameters: Values we want to pass followed with the arguments passed through successHandler.
            table.cell(row, 0).data(JSON.parse(response).text);
            console.log(message);
        ,
        $(this).parents('tr'),//Row value we want to pass for the callback.
        actionName + ' was successful'//Message value we want to pass for the callback.
    )

或者在你的情况下:

arr[c.name] = callbackCreator(function(url) 
        callback(url);
    ,
    c.url
);

【讨论】:

以上是关于Javascript:将自定义参数传递给回调函数的主要内容,如果未能解决你的问题,请参考以下文章

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

JavaScript:如何将多个参数传递给对象成员内的回调函数?

将自定义参数传递给 uibutton #selector swift 3

如何在 Javascript .filter() 方法中将额外参数传递给回调函数?

Firebase 动态链接将自定义参数传递给 iOS 和 android

将自定义启动参数传递给 detox