将一个带参数的函数作为参数传递?

191

能否将带参数的JavaScript函数作为参数传递?

例如:

$(edit_link).click( changeViewMode( myvar ) );

5
看起来像是 JQuery,很可能就是它,但这并不重要。无论你使用什么 JavaScript 库,其参数和函数的使用都是相同的。 - Guffa
1
如果你正在使用React,请考虑查看https://dev59.com/1VgR5IYBdhLWcg3wZcm1。 - Michael Freidgeim
7个回答

301
使用“闭包”:
$(edit_link).click(function(){ return changeViewMode(myvar); });

这将创建一个匿名临时函数包装器,该函数包装器知道参数并将其传递给实际的回调实现。


3
如果你想在一个对象上调用一个函数,你需要调用bind()。例如:myObj.click( function() { this.doSomething(); }.bind( myObj ) ); 这会把 "this" 指向myObj。 - Eli
1
处理大量这些东西时,这不是一个性能问题吗?例如,您正在渲染一行中的 onPress,并且您有10,000行。这会为每个行创建一个新的匿名临时函数包装器。还有其他方法可以做到这一点吗? - Joshua Pinter
3
这个技巧本身并不是问题。如果您需要调用相同的函数10,000次,可以将包装器保存在变量中,这样只需创建一次即可。如果您需要传递10,000个不同的上下文,那么很少有什么可以做的。要注意避免过早进行优化:与性能一样,您需要测量以查看是否存在问题。今天的JavaScript引擎非常强大,可能会以令人惊讶的方式优化代码。 - Ferdinand Beyer
@FerdinandBeyer 太棒了,感谢你的提示。我的一个朋友告诉我这是不好的做法,应该在constructor方法中使用this.myFunction = this.myFunction.bind(this)。但正如你所说,当你必须为每个上下文传递不同的参数时,例如单击以打开该行详细信息页面的所有不同行时,这是不可避免的。 - Joshua Pinter
@FerdinandBeyer,假设myvar是一个字符串,在传递changeViewMode作为闭包的两次连续调用之间发生了更改,但是changeViewMode始终接收myvar的第一个值,我想使用分配给同一myvar变量的不同参数值调用闭包函数。 - nmxprime
1
在ES6中,您可以使用箭头函数简化它。 $(edit_link).click(() => changeViewMode(myvar)); - rodrigombs

52

使用Function.prototype.bind()方法。引用 MDN 的说明:

bind() 方法创建一个新的函数,在调用时设置其 this 关键字为提供的值,给定一系列参数作为调用新函数时提供的参数之前。

所有主流浏览器都支持此方法,包括 IE9+。

你的代码应该像这样:

$(edit_link).click(changeViewMode.bind(null, myvar));

旁注:我假设您处于全局上下文中,即this变量是window;否则请使用null来代替。


谢谢,这对我很有帮助。我是这样使用的: $.ajax(url).done(handler.bind(this, var1, var2)); - Thomas
2
哪个选项更好?使用闭包还是使用bind函数?请告诉我是否有任何性能影响。 - Varun
5
为什么 bind 操作比闭包慢? - Michał Perłakowski
我一直在使用 fn.bind(this) 来解决回调函数中可怕的 this 混淆问题,但是没有理解 bind 的更广泛用途 - 但现在我明白了!谢谢。 - flatpickles

19

不行,但您可以传递一个没有参数的函数,并执行以下操作:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

所以你正在传递一个没有参数的匿名函数,该函数然后使用闭包中的变量调用您的带参数函数。


15

或者如果你正在使用es6,则应该能够使用箭头函数

$(edit_link).click(() => changeViewMode(myvar));

8
是的,就像这样:
$(edit_link).click(function() { changeViewMode(myvar) });

3

你可以做到这一点

var message  = 'Hello World';

var callback = function(){
alert(this)
}.bind(message);

然后

function activate(callback){
  callback && callback();
}

activate(callback);

如果您的回调函数包含更灵活的逻辑,可以传递对象。

演示


2
这是一个按照费迪南德·贝耶的方法编写的示例:
function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

在这个例子中,“参数值”通过函数包装从函数1通过函数2传递到函数3。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接