2015-03-03 52 views
-2

这是来自Avaylo Gerchev博客文章的一个示例,它解决了IIFE的问题。下面的代码块返回4重复“未定义”设计对策:为什么此代码返回未定义4次而不是数组值?

function printFruits(fruits){ 
    for (var i = 0; i < fruits.length; i++) { 
    setTimeout(function(){ 
     console.log(fruits[i]); 
    }, i * 1000); 
    } 
} 

printFruits(["Lemon", "Orange", "Mango", "Banana"]); 

Avaylo然后展示如何产生什么(我)本来第一代码块的预期输出(它输出的值阵列):

function printFruits(fruits){ 
    for (var i = 0; i < fruits.length; i++) { 
    (function(){ 
     var current = i;     // define new variable that will hold the current value of "i" 
     setTimeout(function(){ 
     console.log(fruits[current]); // this time the value of "current" will be different for each iteration 
     }, current * 1000); 
    })(); 
    } 
} 

printFruits(["Lemon", "Orange", "Mango", "Banana"]); 

我明白,IIFE创建一个新的范围。我不明白的是,为什么第一块代码不会产生(对我来说)返回数组中值的预期输出。我一直在盯着这几天,因此我得出结论,我的JavaScript知识缺少一些基本的东西。

谢谢任何​​见解!

+0

http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – 2015-03-03 11:39:34

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide /closures#Creating_closures_in_loops.3A_A_common_mistake – 2015-03-03 11:39:52

+0

(tl; dr)当setTimeout函数运行时,它将始终引用循环中使用的同一个变量'i',并且因为该循环早已结束,其值始终等于'fruits。长度“。) – JJJ 2015-03-03 11:42:58

回答

0

在第一个代码块中,变量“i”不能被闭包访问,因为setTimeout只定义了要运行的代码,但实际上并没有在定义上运行它,只是在稍后。

将闭包关闭并立即运行(最后使用括号())可以在每次迭代中保存“i”的值,以便在setTimeout运行时可以访问它。

相关问题