Потому что let действует в рамках блока
{
}
, а var в рамках функции
function() {
}
.
Когда ты пишешь
for (let i=0; i < button.length; i++)
button[i].onclick = function () {
alert(i);
}
это можно считать шорткатом для
for (let i=0; i < button.length; i++) {
button[i].onclick = function () {
alert(i);
}
}
соответственно в рамках блока let i каждый раз своя, и при вызове созданной функции берётся i из этого блока.
А когда ты пишешь так:
for (var i=0; i < button.length; i++) {
button[i].onclick = function () {
alert(i);
}
}
это шорткат для
var i;
for (i=0; i < button.length; i++) {
button[i].onclick = function () {
alert(i);
}
}
и, соответственно, когда ты кликаешь, берётся то значение i которое осталось последним в рамках вышестоящей функции(или глобала), а не уникальное для блока.
Ксли ты сделаешь так:
for (var i=0; i < button.length; i++)
button[i].onclick = function () {
alert(i);
}
i='от так уот';
То при клике alert тебе даст именно последнее значение которое приняло i в рамках функции.
А вообще, прочитай ты уже чёртов
учебник.