It's undefined because the timer mechanism setTimeout hooks the function to doesn't call the function you give it with any arguments (by default), and you've declared k as the function argument. When you call a JavaScript function with fewer arguments than it declares, the value of those arguments is undefined. So the argument k shadows (hides) the loop variable k, and you always see undefined.
To fix it, don't declare k as a function argument:
for (var k = 0; k < 36; k++){
setTimeout(function(){ alert(k)}, k*5000);
// No k here -------^
}
Example (using 500 instead of 5000):
for (var k = 0; k < 36; k++){
setTimeout(function(){ console.log(k)}, k*500);
// No k here -------^
}
But, then you'll have to fix a new problem (the one addressed by this question and its answers): The value of k that all of those callbacks see will be the same (36), because they see k's value as of when they're called (later, once the loop is over), not when they're created.
In ES5 and earlier, I would solve that like this:
function createHandler(k) {
return function(){ alert(k)};
}
for (var k = 0; k < 36; k++){
setTimeout(createHandler(k), k*5000);
}
Example:
function createHandler(k) {
return function(){ console.log(k)};
}
for (var k = 0; k < 36; k++){
setTimeout(createHandler(k), k*500);
}
...although many would create that createHandler function repeatedly in the loop:
for (var k = 0; k < 36; k++){
setTimeout(function(innerk) {
return function() { alert(innerk); }
}(k), k*5000);
}
Example:
for (var k = 0; k < 36; k++){
setTimeout(function(innerk) {
return function() { console.log(innerk); }
}(k), k*500);
}
In ES2015+ ("ES6" and above), I'd solve it like this:
for (let k = 0; k < 36; k++){
setTimeout(() => { alert(k); }, k*5000);
}
...because when you use let within the for like that, it creates a new k for each iteration with a value that doesn't change.
Example:
// REQUIRES ES2015+ SUPPORT
for (let k = 0; k < 36; k++){
setTimeout(() => { console.log(k); }, k*500);
}