我点击一个按钮,然后有一个处理程序。我从来没有理解我是否应该使用闭包,或让处理程序在一个对象中。例如,在HTML中我有,
<button id="b">Go</button>
<button id="c">Go</button>
和JavaScript(带有一些jQuery),
var hdl=function(){
var hdl=function(){
foo+="foo"
console.log(foo)
},
foo=""
return hdl
}()
$("#b").click(hdl)
var obj={
bar:"",
hdl:function(){
this.bar+="bar"
console.log(this.bar)
}
}
var baz=function(){
obj.hdl()
}
$("#c").click(baz)
两者都有效。或者您是否只能使用其中一种?
答案 0 :(得分:3)
事件处理程序始终是实现EventListener接口的函数或对象。我从来没有理解使用EventListener对象而不是函数的任何理由,所以我只看到使用过的函数,但是你可以使用它们。
如果选择一个函数,则由您决定是将函数作为全局函数,匿名声明的函数还是作为对象属性的函数。没有“正确”的答案,因为它取决于您希望如何构建代码。
我的事件处理程序通常是匿名声明的函数,因为这通常是我构建事物的方式,通常不再需要它。 简单是最好的,所以你应该让它变得不再复杂。
闭包只是一个函数体,它比函数的简单执行存活的时间更长,因为其中一些其他函数引用仍处于活动状态。是否使用闭包取决于您的需求以及代码的结构。闭包可以非常方便地保留一些状态而不使用全局变量,但有时候根本不需要它们。
答案 1 :(得分:1)
我认为你在混淆条款。
闭包是JavaScript的范围规则的自然结果,而不是您选择创建的
jQuery click
事件始终需要一个函数。该函数是否附加到对象 - 从而使其成为一种方法 - 并不重要。根据函数的编写方式,它可能形成一个影响你的闭包。
闭包是指函数“记住”定义它的上下文中的变量。
经典的闭包示例是这样的:
for(var i = 0; i < 10; i++)
$("#button" + i).click(function() { alert("you clicked button " + i); });
大多数开发人员都惊讶地发现每个按钮显示10,当外部范围结束时,这是i
的值。发生这种情况是因为循环中声明的每个函数都在i
上形成了一个闭包。这些函数不仅在声明它们时获得i
的值,它们获得实际的i,尽其所能。这就是为什么在创建函数后更改i
会导致创建的函数反映i
的更新值
通过将i传递给函数,打破闭包来修复这样的情况,因为函数参数是按值传递的。
for(var i = 0; i < 10; i++)
(function(localI) {
$("#button" + i).click(function() { alert("you clicked button " + localI); });
)(i);
答案 2 :(得分:1)
您的案例之间的唯一区别是,在其中一个案例中,您将变量(foo)捆绑在一个对象中。以下第三个例子应该明确这一点:
function hdl(variables){
variables.foo += variables.foo;
}
var obj = {foo: ""};
var baz = function(){
hdl(obj);
}
我认为这些替代品中的任何一种都无论如何都优于其他替代品。您应该决定使用哪种解决方案更简单,更容易理解和维护,具体取决于您的特定问题。
例如,在使用对象的版本中,变量是dinamically绑定的,而在带有闭包的版本中,它们是静态绑定的。这意味着对象版本更具可扩展性(使用继承,mixins等),而闭包版本更加严格(但在编译时更容易理解)