Как исправить замыкание в JavaScript с локальной переменной?

У меня есть такой код:

for (let j = 0; j < 5; j++) {
  let кнопка = document.createElement('button');
  кнопка.номер = j;

  кнопка.addEventListener('click', function() {
    console.log(кнопка.номер);
  });

  document.body.appendChild(кнопка);
}

Я создаю несколько кнопок в цикле. Каждой кнопке присваиваю номер, равный индексу цикла. Потом добавляю обработчик клика, который должен выводить этот номер.

Проблема в том, что при клике все кнопки выводят 4 вместо своего номера. Как это исправить, чтобы каждая кнопка показывала правильный номер?

А может просто использовать стрелочную функцию? Она не создает свой контекст this и будет ссылаться на нужную переменную:

for (let j = 0; j < 5; j++) {
  let кнопка = document.createElement('button');
  кнопка.номер = j;
  
  кнопка.addEventListener('click', () => {
    console.log(кнопка.номер);
  });

  document.body.appendChild(кнопка);
}

Так должно сработать без лишних сложностей. Попробуй!

я сталкивался с похожей проблемой! тут дело в замыкании - функция-обработчик клика сохраняет ссылку на переменную кнопка, а не на ее значение. попробуй использовать IIFE (immediately invoked function expression), чтобы создать отдельную область видимости для каждой итерации цикла:

for (let j = 0; j < 5; j++) {
  (function(номер) {
    let кнопка = document.createElement('button');
    кнопка.номер = номер;
    
    кнопка.addEventListener('click', function() {
      console.log(кнопка.номер);
    });
    
    document.body.appendChild(кнопка);
  })(j);
}

так каждая кнопка будет иметь свою собственную копию переменной номер. надеюсь, это поможет!

в твоем случае проблема не в замыкании, а в том, что ты используешь let внутри цикла for. let создает блочную область видимости, поэтому для каждой итерации создается новая переменная j. просто замени let на var:

for (var j = 0; j < 5; j++) {
  var кнопка = document.createElement('button');
  кнопка.номер = j;

  кнопка.addEventListener('click', function() {
    console.log(this.номер);
  });

  document.body.appendChild(кнопка);
}

так каждая кнопка будет иметь свой уникальный номер. также используй this вместо кнопка внутри обработчика.