Почему эта функция распечатывает 0 1 2 вместо 0 1 2 3?
(function fn1(){
for (var i = 0; i < 4; i++) {
var tc=setTimeout(function(i){
console.info(i);
clearTimeout(tc);
}, 10, i);
}
})();
Это был вопрос, заданный в интервью.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


var, конечно, поднимается, поэтому в цикле fortc (синхронно) несколько раз переназначается и заканчивается как окончательныйsetTimeout. Таким образом, каждый раз, когда запускается функция тайм-аута, она ссылается на тот же tc, который ссылается на тайм-аут последней итерации, и очищает его с помощью clearTimeout. Для интерпретатора это выглядит так:
(function fn1() {
var tc;
var i;
for (i = 0; i < 4; i++) {
tc = setTimeout(function(i) {
console.info(i);
clearTimeout(tc);
}, 10, i);
}
})();Если вы хотите распечатать 0 1 2 3, используйте вместо него let (let имеет область действия блока и не поднимается), чтобы дать каждой итерации отдельную привязку для tc:
(function fn1() {
for (let i = 0; i < 4; i++) {
let tc = setTimeout(function(i) {
console.info(i);
clearTimeout(tc);
}, 10, i);
}
})();Спасибо, очень полезно ~
Почему вы убираете тайм-аут?