一堆小封闭与一大封闭

时间:2010-08-15 21:43:45

标签: javascript closures

我有一个谷歌地图,我正在为不同的事情添加事件监听器。例如,我有一个Point对象,对于这个对象,我一直在添加事件:

google.maps.event.addListener(this.marker, 'click', (function(point) {
    return function(event) {
        alert(point.index);
    }})(this));

我有很多这些事件(一个是'click','rightclick','doubleclick'等)。

当我添加事件时,我只在当前点附近创建一个闭包。然而我想要做的只是:

var point = this;

google.maps.event.addListener(this.marker, 'click', function(event) {
    alert(point.index);
});

由于两个原因,我一直在避免这种情况。

一个是我看到人们对Javascript的了解比我使用“个人”闭包更多,所以我认为他们必须有充分的理由。

第二个是因为(而且我对Javascript的解释方式一无所知)我想知道创建一个大型闭包是否会捕获我将不会在我的事件函数中使用的所有其他变量(例如'var color “)。这会导致性能问题吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

当你的观点没有变化时,它应该没有问题。所以在你的第二个例子中做到这一点很好:

var point = this;

google.maps.event.addListener(this.marker, 'click', function(event) {
  alert(point.index);
});

一般情况下,当你的点必然发生变化并且你需要处于一个独特的状态时,你会对事件处理函数进行另一次闭包,例如在循环中:

for(var i = 0, len = points.length; i < len; i++) {
  google.maps.event.addListener(points[i].marker, 'click', (function(point) {
    return function(event) {
      alert(point.index);
    }
  })(points[i]));
}

如果在我的例子中我们没有使用闭包,那么在事件被触发的那一刻我们就会引用数组点的最后一个元素。

答案 1 :(得分:1)

您的示例都会对名为point的内容创建闭包。在第一个中,point是外部匿名函数的参数,而在第二个中,point是局部变量。但不管怎样,它最终都是由一个匿名函数关闭的。

创建一个接受一个命名参数然后立即用参数调用它的匿名函数只是将值绑定到范围内名称的一种方法。

(function(x) { 
    // now x has the value
})(getValue());

或者:

var x = getValue();
// now x has the value

不同之处在于,通过使用函数,可以确保x位于其自己的命名空间中,并且不会与封闭范围中的任何其他x合并。也就是说,值是可维护性,而不是执行速度。

哪个会表现更好?找出答案的唯一方法是在多个浏览器上进行测试 - 它们都有自己的执行引擎。

认为创建越多的匿名函数似乎是合理的,发生的分配越少。所以你的第二个例子,匿名函数较少,可能表现更好。但是,如果没有在你关心的每个浏览器中进行测试,那就是毫无根据的猜测。