Строго не обязательно передавать i в функцию, ее можно присвоить локальной переменной внутри.
var vals = [1, 2, 3];
for(var i = 0; i < vals.length; i++) {
(function() {
var num = i
window.setTimeout(function() {alert(vals[num]);}, 1000);
})();
}
Требуется "function () {block} ()", потому что в Javascript не было правильных блочных лексических переменных. В последних выпусках добавлено «let», что делает это возможным:
var vals = [1, 2, 3];
for(var i = 0; i < vals.length; i++) {
let num = i
window.setTimeout(function() {alert(vals[num]);}, 1000);
}