Как работает область видимости в цикле for? - PullRequest
0 голосов
/ 25 мая 2018

Когда я создал 5 кнопок в цикле и нажал, значение i всегда равно 6

function createButtons() {
   for (var i = 1; i <= 5; i++) {
     var body = document.getElementsByTagName("BODY")[0];
     var button = document.createElement("BUTTON");
     button.innerHTML = 'Button ' + i;
     (function(num) {
       button.onclick = function() {
          alert('This is button ' + num);
       }
     })(i);
     body.appendChild(button);
   }
}

, но когда я изменяю область действия i, чтобы заблокировать область действия (используя IIFE или ключевое слово let), он дает правильное значение i.Как это работает под капотом JavaScript?

1 Ответ

0 голосов
/ 25 мая 2018

Я разделил ваши функции на incorrect и correct один.

Версия incorrect - это то, что вы просите.Версия correct - это то, что вы уже выяснили, но не знаете, почему она работает.

В неправильной версии значение i всегда будет обновляться до самого последнего значения, потому что i принадлежит функции createButtons и используется всем обработчиком onclick, и он изменяется в цикле.

В правильной версии значение i присваивается IIFE какnum, а num принадлежит IIFE, а не createButtons.

Из-за этого num является фиксированным, поскольку для каждого цикла создается новый num, поэтому он не используется совместно сдругой обработчик onclick.

Почему?Вот как замыкание работает в JavaScript.

Прочтите это для более глубокого понимания закрытия JavaScript.

function createButtons_incorrect() {
   for (var i = 1; i <= 5; i++) {
     var body = document.getElementsByTagName("BODY")[0];
     var button = document.createElement("BUTTON");
     button.innerHTML = 'Bad ' + i;
     button.onclick = function() {
        alert('This is button ' + i);
     }
     body.appendChild(button);
   }
}

function createButtons_correct() {
   for (var i = 1; i <= 5; i++) {
     var body = document.getElementsByTagName("BODY")[0];
     var button = document.createElement("BUTTON");
     button.innerHTML = 'Good ' + i;
     (function(num){
       button.onclick = function() {
          alert('This is button ' + num);
       }
     })(i);
     body.appendChild(button);
   }
}

createButtons_incorrect();
document.body.appendChild(document.createElement('br'));
createButtons_correct();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...