【问题标题】:A bunch of little closures vs one big one一堆小闭包 vs 一个大闭包
【发布时间】:2010-08-30 02:41:12
【问题描述】:

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

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

我有很多这样的事件(一个用于“单击”、“右键单击”、“双击”等)。

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

var point = this;

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

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

一个是我见过比我更了解 Javascript 的人使用“个人”闭包,所以我认为他们一定有充分的理由。

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

感谢您的帮助!

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    您的两个示例都在名为 point 的东西上创建了闭包。在第一个中,point 是外部匿名函数的参数,在第二个中,point 是一个局部变量。但无论哪种方式,它最终都会被匿名函数关闭。

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

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

    或者:

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

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

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

    认为创建的匿名函数越多,发生的小分配就越多,这似乎是合理的。因此,您的第二个示例使用较少的匿名函数,可能会执行得更好。但这纯粹是毫无根据的猜测,没有在您关心的每个浏览器中进行测试。

    【讨论】:

    • 感谢您的回复。但是,假设在我的第二段代码中我有“var lotsofmemory = new Array(10000);”在“var point = this”之前。当不再需要“lotsofmemory”时,它是否仍然会浪费空间,因为它已被匿名函数关闭? (我知道像 Chrome 这样的浏览器可能会启发式地优化这类事情,但是 IE 呢?)
    • 如果您编写一个重复执行此操作的脚本,则存储匿名。列表中的函数,你应该能够衡量它的效果,如果有的话。
    【解决方案2】:

    在你的观点不变的情况下应该没有问题。所以像你的第二个例子那样做就可以了:

    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]));
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      相关资源
      最近更新 更多