2012-03-15 85 views
-1
this.config = { 
    source: psource, 
    _events: [ 
     'value1', 
     'value2', 
     'value3' 
    ] 
}; 

// Add callbacks to source 
var that = this; 
for (var i = this.config._events.length - 1; i >= 0; i--) { 
    var name = this.config._events[i]; 
    console.log(name); // correct 

    $(this.config.source).on(name, function() { 
     console.log(name); // value1 
     console.log(that.config._events[i]); // undefined 
    }); 
} 

我看不出这里有什么问题。我删除了所有复杂的版本,并放入最简单的版本,它根本不想工作。第一个console.log正确输出所有正确的名称,但它的行为像循环一次发生,然后再次为内部console.log的。闭环影响循环中闭合函数中的变量

任何人都可以看到有什么问题吗?

+0

声明“闭包正在影响所有事情,而不仅仅是这一点”并未描述问题 - 闭包如何工作。封闭范围中的所有变量都包含在闭包中。 – nrabinowitz 2012-03-15 18:25:41

+0

请使用更具描述性的内容修改问题的标题。我认为你应该提到术语'for循环' – viebel 2012-03-15 18:37:04

+0

重复http://stackoverflow.com/questions/2192348/closures-in-a-for-loop – viebel 2012-03-16 10:56:56

回答

2

在该块

console.log(that.config._events[i]); // undefined

i将结束是-1每次你关闭被调用时。

你将不得不做类似的东西,以创造一个封闭周围i

$(this.config.source).on(name, function(i) { return function() { 
     console.log(name); // value1 
     console.log(that.config._events[i]); // undefined 
    }; 
}(i)); 
+0

更好的是,将'i'作为参数传递给''。 on'方法,并使用'event.i'访问变量。有关我的建议的更多详细信息,请参阅'.on()'的文档:http://api.jquery.com/on/ – 2012-03-15 18:26:53

+0

@RobW这可能适用于这种情况,因为我是数字基元。然而,我故意选择了这个解决方案,以便操作员能够理解,在闭包中保持对变量的引用并不等于在闭包创建时保持对它的当前值的引用。 – Damp 2012-03-15 18:31:51

-1

在Javascript中,不建议定义for循环中的功能。

相反,您应该使用一个JavaScript库,例如提供each例如underscore。然后你的代码将如下所示:

_.each(this.config._events, function(e) { 
     $(this.config.source).on(name, function() { 
      console.log(e); 
     }); 

您可能想要先颠倒数组。

这里是doc for _.each

你也可以使用jQuery的$.each它提供了一个类似的界面。

+1

-1在'for'循环中定义一个函数是完全安全的。你只需要注意变量的范围以及闭包的工作方式。 – Damp 2012-03-15 18:38:02

+1

我用'危险'取代'不安全'。这导致了很多混乱。实际上,'jslint'不允许。请投回 – viebel 2012-03-15 18:40:35

+1

也没什么危险的。它的工作原理应该如此。我支持我的-1。 'jslint'不允许它是他们的选择,而不是javascript问题。 – Damp 2012-03-15 18:44:22