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 中的一等对象,没有闭包就很难做到。想象一下,将函数中引用的每个变量都作为参数传递——在这种情况下,callback
和 url
以及参数是通过值传递还是通过引用传递的所有令人头疼的问题。
我认为值得注意的是,并不是闭包本身使它工作,而是更具体地说,这个闭包代码包括传递一个参数——这使得按值传递代替引用保留在原始闭包中,从而克服了原始问题。我认为这使解释更加完整。【参考方案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:如何将多个参数传递给对象成员内的回调函数?
将自定义参数传递给 uibutton #selector swift 3
如何在 Javascript .filter() 方法中将额外参数传递给回调函数?