Javascript 为什么要将整个函数定义作为参数传递,而不仅仅是可以重用的函数名?

Javascript 为什么要将整个函数定义作为参数传递,而不仅仅是可以重用的函数名?,javascript,callback,Javascript,Callback,前者在JavaScript中似乎更“时髦”,我不明白为什么 编辑:对于这个可能是重复的问题,我感兴趣的是为什么,而不是如何。另外一个只问标题中的“闭包”的问题不会引起那些还没有把它和闭包联系起来的人的注意。tl;dr:因为许多功能实际上没有被重用 我想你回答了你自己的问题: 。。。而不仅仅是可以重用的函数名 其中许多是“一次性”案例。代码行只执行一次,传递的函数不必重用 例如,如果我想将事件处理程序绑定到主体,并且我不想在任何地方重用事件处理程序,那么我为什么要编写 function body

前者在JavaScript中似乎更“时髦”,我不明白为什么


编辑:对于这个可能是重复的问题,我感兴趣的是为什么,而不是如何。另外一个只问标题中的“闭包”的问题不会引起那些还没有把它和闭包联系起来的人的注意。

tl;dr:因为许多功能实际上没有被重用


我想你回答了你自己的问题:

。。。而不仅仅是可以重用的函数名

其中许多是“一次性”案例。代码行只执行一次,传递的函数不必重用

例如,如果我想将事件处理程序绑定到
主体
,并且我不想在任何地方重用事件处理程序,那么我为什么要编写

function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
并且不必要地用
bodyEventHandler
污染当前范围

document.body.addEventListener('click', function() {...});
具有相同的效果,不会污染范围,并将函数定义保留在使用它的位置

JavaScript非常受事件驱动,大多数事件处理程序实际上不会在其他任何地方重用


在使用函数的地方保留函数定义也是一个常见的原因。有些函数非常简单,但给它们起描述性名称可能并不容易

例如,如果你不熟悉“拔毛”这个词,你能理解什么吗

var names = users.map(pluck('name'));
真的吗?也许你可以从其他变量的名字中推断出来

但是,

var names = users.map(function(user) { return user.name; });
这一点马上就清楚了

事实上,现在ECMAScript 6引入了箭头函数,这与其他语言中的lambda函数类似,您将更经常地看到这些函数:

var names = users.map(user => user.name);

我还认为,当你通过一个函数时,你对引擎盖下到底发生了什么有一个误解:

。。。将整个函数定义作为参数传递,而不仅仅是函数名


foo(bar)
不会将名称“bar”传递给
foo
。它传递变量
bar
引用的函数对象。这与
foo(function(){…})
没有什么不同。唯一的区别是我们没有(暂时)将函数存储在变量中。

可能重复的好解释,坏例子:正确处理事件意味着以后还需要调用
removeEventListener
,以防止内存泄漏,这意味着您需要在某处保留对函数处理程序的引用。Map/foreach等是更好的例子。@Mike'Pomax'Kamermans-不需要调用
removeEventListener()
来防止内存泄漏。DOM元素具有eventListener这一事实并不阻止它被垃圾收集。GC非常聪明,能够识别出DOM元素无法访问的情况。对于今天的浏览器来说,这通常是正确的,但除了“从DOM中删除DOM节点”外,还有更多情况需要清理eventlistening。React应用程序的迅速普及立即浮现在我的脑海中。谢谢Felix。有时候,确认和学习新信息一样重要。简单地说“许多函数实际上没有被重用”对许多程序员来说是亵渎神明的。所以听到它会有帮助。