指定命名函数和匿名函数作为处理程序的区别?

3
当在jQuery中指定处理程序函数时,指定命名函数和将命名函数包装在匿名函数中是否有区别?
指定命名函数:
$( "#foo" ).on( "click", bar);

将命名函数包装在匿名函数中与直接使用命名函数的区别:

$( "#foo" ).on( "click", function() {
  bar();
})

2
在第二个中,this 不会绑定在 bar 中。 - Barmar
2
为了澄清@Barmar的评论,this 在第二个绑定,但不是绑定到被点击的元素。两者之间的主要区别在于调用上下文,这决定了this所指的内容。 - JAAulde
3个回答

1
它们几乎等效。使用匿名函数的等效版本如下:
$( "#foo" ).on( "click", function(event) {
    bar.call(this, event);
});

当jQuery运行事件处理程序时,它将上下文绑定到目标元素。 this.bar() 将该绑定传递给函数。
如果您想使用 .off() 删除特定处理程序,则需要使用具有命名函数的第一个版本。如果使用匿名函数,则无法在删除时引用它。

你确定可以将 bar() 链接到一个元素上吗?bind()(或者 call / apply)呢? - adeneo
我没有链接任何东西。我只是复制了jQuery在调用事件处理程序时将“this”绑定到事件目标的方式。 - Barmar
我必须使用 bar.call(this, event) 来正确模拟它吗? - Barmar
1
好的,这是一种方法!this 是一个本地 DOM 元素,为什么它会有一个 bar() 方法?使用 call() 调用并设置 this 的值将可以正常工作。 - adeneo
1
我认为jQuery在$.fn.on中使用了bar.apply(this, arguments) - adeneo

1

正如其他人所说,命名函数通常意味着您拥有对函数对象的引用,这使您可以轻松地删除事件处理程序,而不必采取不太优雅的策略。

但是,如果您使用JavaScript调试器,则一般情况下命名函数更好。在查看堆栈跟踪时,如果每个堆栈帧都有一个合理的名称而不是“匿名函数”,那么真的很好。

PS-您可以像这样命名函数表达式

$( "#foo" ).on( "click", function bar() {
    // "this" will be bound to the clicked element
});

给你简洁的语法,一个命名函数以便稍后移除事件处理程序,有用的绑定“this”,以及更好的堆栈跟踪。

1

只有当您希望稍后能够再次调用该函数时才需要这样做。


为什么他不能在第二个版本之后调用 bar 函数? - Barmar
我误读了这个例子。你是正确的。'bar'仍然是相同的函数,无论在哪里调用它。我以为在第二个例子中他是在放置函数bar的代码,而不是调用它。 - John C

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