Чтобы понять это, вам нужно понять, как JavaScript основан на событиях и как работают области, поэтому, я полагаю, он используется в качестве вопроса для интервью.
В основном, JavaScript основан на очереди событий. В приведенном примере кода setTimeout
не выполняет код немедленно, но сообщает движку, что код должен сработать за 100 мс.
Однако for
l oop выполняется немедленно , Само по себе это не будет проблемой, если вы используете определение переменной области блока, например let i = 0
. Например, следующий код напечатает 0, 1, 2:
for (let i = 0; i < 3; i+=1) {
setTimeout(function() {
console.log(i)
}, 100)
}
Однако в коде используется var
, который «поднимается» в начало определения функции, или в этом случай, верхняя часть фрагмента / файла. Таким образом, на самом деле код должен выглядеть следующим образом:
var i;
for (i = 0; i < 3; i+=1) {
setTimeout(function() {
console.log(i)
}, 100)
}
Это имеет интересный эффект: теперь for l oop выполняется три раза, увеличивая i
до значения 3
. Затем после завершения выполнения for l oop вызывается функция обратного вызова setTimeout
, которая имеет то же значение i
в своей области видимости (потому что она была поднята). Вот почему он печатает 3 три раза.