6

At least is what I think it happens in this case:

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);
}

I get this error Uncaught TypeError: Cannot read property 'name' of undefined, so it looks like inside the setTimeout listener function the people variable is not accessible. Why and how can I fix it?

2
  • This is a very common mistake, see this question: stackoverflow.com/questions/5226285/… Commented Aug 26, 2013 at 13:31
  • 1
    No, it means that people[i] is not defined. If people was not in scope, you would get something like Uncaught ReferenceError: people is not defined. Commented Aug 26, 2013 at 13:31

1 Answer 1

24

Actually people array is ok. What it happens is that your i is actually 2 and there is no third element in the array. That's why you get this error. Here is the solution:

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();

Here is a jsfiddle http://jsfiddle.net/krasimir/XDfLu/2/

The long answer: when you use setTimeout you are passing a function to it. That function is called in the future and the things which you make there are also executed in the future. At that moment (the future one) your i is no longer 0 or 1. It is actually 2 because your loop ended. The provided solution uses additional closure to create one more scope/context. And once the function passed to setTimeout is called it looks for a i variable. There is no such a thing in its scope, so it goes one level up. And there is the actual value which we need.

Sign up to request clarification or add additional context in comments.

3 Comments

Care to explain the solution? What is it and why does it solve the problem?
Answer edited. (I'm not sure that I explained it well enough).
Nearly. Even though you added a function call, it doesn't matter whether the function is a closure or not. The only important thing is that the function is executed and creates a new scope through that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.