ksa, предложу немного измененный вариант исходного кода:
function printNumbersInterval20_100() {
var i = 1, point = 'start';
var timerId = setInterval(function() {
console.log(i + ' ' + point);
if (i == 20) clearInterval(timerId);
i++;
}, 100);
point = 'finish';
}
В логах пишется:
1 finish
2 finish
.........
20 finish
Кажется механизм передачи переменных следующий:
1. При выполнении функции printNumbersInterval20_100() создается анонимная функция, которая привязывается к таймеру. Также ей передается ссылка на VariableEnviroment (а может и на LexicalEnvironment) от вызывающей функции, но все-же это не передача параметров функции.
2. printNumbersInterval20_100() уже может выполнится полностью, когда таймер сработает первый раз, но завершение функции будет означать лишь остановку действий внешней функции, а VariableEnviroment останется висеть в памяти. Примерно как это происходит с замыканиями - внешняя функция вроде завершена, но список переменных из памяти не выгружается пока на них будут ссылаться другие функции.
3. Анонимная функция при срабатывания таймера берет значения из переданного объекта VariableEnviroment. Т.е. ей не передается снимок переменных в момент создания анонимной функции из printNumbersInterval20_100(), а именно переменные в функцию попадают по ссылке в момент сработки таймера.
Еще один вывод: если таймеров создается много, то необходимо их после выполнения(!) чистить "ручками", а не оставлять на без присмотра, иначе будет копиться мусор и могут появиться тормоза. Где-то на форуме видел рекомендации про чистку при создании тысяч таймеров в обязательном порядке, иначе система может тормозить.
Если я не прав, прошу поправить.