JavaScript setTimeout无法访问函数变量

时间:2013-08-26 13:29:46

标签: javascript settimeout

至少我认为在这种情况下会发生这种情况:

function MyFunc() {
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43});
    for (var i=0; i<people.length; i++) {
        setTimeout(function() { ShowIt(people[i].name) }, 1000); // !!!
    }
}

function ShowIt(name) {
    alert(name);
}

我收到此错误Uncaught TypeError: Cannot read property 'name' of undefined,因此看起来在setTimeout侦听器函数内部people变量无法访问。为什么以及如何解决?

1 个答案:

答案 0 :(得分:22)

实际上数组还可以。它发生的是你的i实际上是2并且数组中没有第三个元素。这就是你得到这个错误的原因。这是解决方案:

function MyFunc() {
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43});
    for (var i=0; i<people.length; i++) {
        (function(i) {
            setTimeout(function() {             
                ShowIt(people[i].name) 
            }, 1000);
        })(i);
    }
}

function ShowIt(name) {
    console.log(name);
}

MyFunc();

这是一个jsfiddle http://jsfiddle.net/krasimir/XDfLu/2/

答案很长:当你使用setTimeout时,你正在向它传递一个函数。将来会调用该函数,并且您将在此处执行的操作也将在未来执行。在那一刻(未来一个)你的i不再是0或1.它实际上是2因为你的循环结束了。提供的解决方案使用额外的闭包来创建另一个范围/上下文。一旦调用传递给setTimeout的函数,它就会查找一个i变量。它的范围没有这样的东西,所以它升级了一层。而且我们需要的是实际价值。