2013-03-28 49 views
1

这些函数之间有什么区别?为什么第一个工作,第二个不能按预期工作?JavaScript中循环中闭包的区别

http://jsfiddle.net/GKDev/x6pyg/(这工作)

http://jsfiddle.net/GKDev/bv4em/(这是不是)

我试图遍历输入元素,并添加的onfocus事件对他们说:

for (var i = 0; i < helpText.length; i++) { 
    var item = helpText[i]; 

    document.getElementById(item.id).onfocus = function() { 
     showHelp(item.help); 
    }; 
} 
+0

可能重复的[使用Javascript闭合环内 - 简单实用示例](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – bfavaretto

回答

2

在您的非工作示例中,当调用匿名函数时,item具有for循环完成执行时保存的最后一个值。这是因为此变量属于包含for循环的父函数。

在你的工作示例,您创建一个新的功能,在item当前值传递像这样:

function (help) { 
      return function() { 
       showHelp(help); // <-- This will be the value enclosed in this anonymous function 
      }; 
     }(item.help); // <-- Calls an anonymous function passing in the current value 

这将创建围绕该值的新的闭包,因为它是迭代过程中存在。当匿名函数被调用时,它使用该本地值。

2

它被视为:

var item; 

for (var i = 0; i < helpText.length; i++) { 
    item = helpText[i]; 

    document.getElementById(item.id).onfocus = function() { 
     showHelp(item.help); 
    }; 
} 

循环以前任何焦点回调火灾结束,在这一点上item是分配的最后一个项目。

1

这实际上很简单。

在第一种情况下,您将在作为本地副本的闭包中传递item.help。它就像一个范围内的囚犯。外面发生了什么,没人关心。

for (var i = 0; i < helpText.length; i++) { 
     var item = helpText[i]; 
     document.getElementById(item.id).onfocus = function (help) { 
      return function() { 
       showHelp(help); 
      }; 
     }(item.help); 
    } 

在第二个,没有闭合保留的项的值,这意味着,当项目进行评价时,它计算其实际值,即:该数组的最后一个元件,由于最后一个循环将其值设置为数组的最后一个值。

for (var i = 0; i < helpText.length; i++) { 
    var item = helpText[i]; 
    document.getElementById(item.id).onfocus = function() { 
     showHelp(item.help); 
    } 
    }