如何正确处理JavaScript事件中的闭包?

如何正确处理JavaScript事件中的闭包?,javascript,events,svg,closures,Javascript,Events,Svg,Closures,我正在构建自己的类(用于SVG对象),最近开始向其中添加事件处理。按照标准模式,我喜欢这种类型的交互 svgobj.bind('click', function(e){ // do stuff here on click with svgobj }); 即使我使用jQuery附加事件,这个“绑定”也不是jQuerybind()方法,svgobj也不是jQuery对象 我遇到的问题是,如果我创建多个对象,那么匿名函数中的svgobj引用将指向最后创建的svgobj,而不是触发事件的对象。因此

我正在构建自己的类(用于SVG对象),最近开始向其中添加事件处理。按照标准模式,我喜欢这种类型的交互

svgobj.bind('click', function(e){
  // do stuff here on click with svgobj
});
即使我使用jQuery附加事件,这个“绑定”也不是jQuery
bind()
方法,svgobj也不是jQuery对象

我遇到的问题是,如果我创建多个对象,那么匿名函数中的
svgobj
引用将指向最后创建的
svgobj
,而不是触发事件的对象。因此,如果我的事件负责更改对象的状态,例如,无论我单击哪个对象,只有最后一个对象更改状态

我知道这是一个结束问题,在一位同事的帮助下,我找到了一个解决办法,但这是一个非常丑陋的问题。它涉及到将函数包装在一个自动执行的匿名函数中,我将正确的
svgobj
传递给该函数,并返回原始函数,下面是一个示例

svgobj.bind('click', (function(target){
    return function(e){
      // do stuff here on click with target, i.e. the correct svgobj
    }
  })(svgobj)
);
你可以在这里看到一个例子。通过单击红色/绿色区域,可以测试拖动事件(通过圆形零件)和更改状态事件


有没有更好的办法来解决这个问题?我希望避免每次想对事件执行某些操作时都必须使用两个匿名函数。也许有一种方法可以将自执行函数移动到一开始调用事件的方法中,这样“在外部”看起来仍然只有一个常规函数作为参数传递?

如果您在那里使用的是一个相当标准的约定,那么它将被视为相当地道的javascript

如果你真的想让它更干净,你可以像这样拆分匿名函数

function getCallBack(target){
   return function(e){
       //Do stuff with target
   }
}

svobj.bind('click',getCallBack(svobj));
总的来说要长一些,但是它清理了bind调用,然后您可以添加注释来澄清回调函数的使用。如果您计划重用该代码,那么它也很有用

更新 由于您似乎正在使用自定义绑定函数,因此可以通过设置
`var that=this然后在内部函数中引用
<无论使用多少级别的内部函数,将始终引用调用对象

但是,由于您显然在使用jQuery,因此我建议您只使用jQuery绑定函数,并简化自己。

通过使用(我假设jQuery是如何使用的),函数中的
this
成为目标,因此不必在函数中使用变量
svobj

svgobj.bind('click', function (e) {
  // do stuff here on click with `this` or `$(this)`
});

如果您确实希望当前
svgobj
的副本与
.bind
时的副本完全相同,那么您需要在其自身的范围内捕获它,以保护它不受更改。您描述为“丑陋”的lambda函数方式很可能是实现这一点的最简单方式。

我为您的混淆道歉,但这不是jQuery bind()方法。我修改了问题以澄清这一点。这确实使事情变得更整洁,至少在一种情况下效果很好,但这仍然意味着在这些情况下,我需要为“一个活动”编写两个函数。我想我是想弄清楚jQuery是如何做到的,当你做$(obj)时('click',function(e){this});这最终是指obj而不是回调?(我试过查看jquery源代码,但有点过头了:-/)如果这不是jquery绑定方法,它是自定义绑定方法吗?它的行为类似于jQuery绑定方法,而不像原生的JS绑定方法。如果它是一个自定义方法,您可以通过设置
var that=this,将其保持在封闭函数中的原始值然后在内部函数中引用它。