Вот есть код:
for (let i=0; i < button.length; i++)
button[i].onclick = function () {
alert(this);
}
Он ставит функцию обработчик на событие и значение переменной i в придачу.
На каждой итерации цикла новое значение i запасает в свой button элемент. А почему var вместо let так не может? Почему бы ему запасти для кажого button свой window.i ?