学习Javascript,为什么这两个函数的行为不同?

时间:2013-08-23 02:43:06

标签: javascript

学习Javascript并无法弄清楚为什么这两个函数不同。我看到了这个例子(我在函数中添加了名称):

var txt = ["a","b","c"];

for (var i = 0; i < 3; ++i ) {    
    setTimeout((function myBind(msg) { 
      return function myAlert() { alert(msg); } 
    })(txt[i]), 1000);        
}​

我看到正在返回一个调用alert的函数。所以我想,为什么不直接把它归还:

var txt = ["a","b","c"];

for (var i = 0; i < 3; ++i ) {    
    setTimeout( function() { alert(txt[i]);} ,1000);        
}​

这最终警告'未定义'。我明白这是因为它试图访问txt [3],因为一秒钟后循环结束并且我已经设置为3,但我不明白原始设置是如何避免这个问题的。

4 个答案:

答案 0 :(得分:1)

您需要阅读有关闭包的内容。请参阅此回答How do JavaScript closures work?以了解它们。

答案 1 :(得分:1)

示例1

闭包会立即执行脚本,并允许您在内部传递参数 它存储并保存在该函数中。参数== PARAM

(function(param){})(parameter)

在您的示例中,该函数返回另一个函数,该函数将由setTimeout执行。

(function(param){
 return function(){
  alert(param)
 }
})(parameter)

当你先前将参数传递给函数时,它将返回正确的值。

示例2

setTimeout被快速调用3次,但参数不存储在任何地方 所以从txt&amp;中得到最后一个值i并且在执行setTimeout之前循环结束,值为3


基本上在第一个例子中,您将每个txt [i]存储在您使用这些闭包创建的每个函数中。

在第二个中你没有将txt [i]存储在任何地方。你只需告诉setTimout函数提醒txt [i],在1秒之后是for循环创建的最后一个。

答案 2 :(得分:0)

在第一个版本中,txt[i]已绑定到新变量msg,该变量是正在创建的每个function的不同位置。

在第二个版本中,i与每个function的位置相同,因为i的范围更远;每次循环都没有创建新的i变量。

答案 3 :(得分:0)

这是一个并发问题。

setTimeout为每次执行创建一个“线程”,但在超时到期之前不会评估该函数。

所以,经过一秒钟,当第一个超时到期时,你的for循环结束了(i有3个值),所以访问txt[i]返回undefined。 尝试使用i

在函数内打印console.log的值