Как делает функцию в цикле (который возвращает другую функцию), работа? [дубликат]

3 ответа

Когда вы назначаете функцию обработчику кликов , создается замыкание .

Обычно замыкание формируется, когда вы вкладываете функции, внутренние функции могут ссылаться на переменные, присутствующие во внешних включающих функциях, даже после того, как их родительские функции уже выполнены.

Во время выполнения события щелчка обработчик обращается к последнему значению переменной i , потому что эта переменная хранится в закрытии.

Как вы заметили,оборачивая функцию обработчика кликов, чтобы принять переменную i в качестве аргумента, и возвращая другую функцию (в основном создавая другое закрытие), она работает так, как вы ожидаете:

for ( var i = 0; i < 4; i++ ) {
  var a = document.createElement( "a" );
  a.onclick = (function(j) { // a closure is created
    return function () {
      alert(j); 
    }
  }(i));
  document.getElementById( "foo" ).appendChild( a );
}

Когда вы выполняете итерацию, фактически создайте 4 функции , каждая функция сохраняет ссылку на i в момент ее создания (путем передачи i ), это значение сохраняется во внешнем замыкании, а внутренняя функция выполняется при событии щелчка

Я использую следующий фрагмент, чтобы объяснить замыкания (и очень базовую концепцию curry ), я думаю, что простой пример может облегчить понимание концепции:

// a function that generates functions to add two numbers
function addGenerator (x) { // closure that stores the first number
  return function (y){ // make the addition
    return x + y;
  };
}

var plusOne = addGenerator(1), // create two number adding functions
    addFive = addGenerator(5);

alert(addFive(10)); // 15
alert(plusOne(10)); // 11
46
ответ дан 29 November 2019 в 06:42
поделиться

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

Решение вашей проблемы - использовать функцию, возвращающую функцию:

a.onclick = (function(k) {return function() { alert(k); }; })(i);
2
ответ дан 29 November 2019 в 06:42
поделиться

Не вдаваясь в подробности, это по существу создает копии переменных экземпляра, оборачивая их в функцию, которая выполняется немедленно и передает обратно функции, которая будет выполнена при щелчке по элементу.

Подумайте об этом так:

function() { alert(i); }  // Will expose the latest value of i
(function(I) { return function() { alert(I); }; })(i); // Will pass the current
                                                       // value of i and return
                                                       // a function that exposes
                                                       // i at that time

Итак, во время каждой итерации цикла вы фактически выполняете функцию, которая возвращает функцию с текущим значение переменной.

Что, если вы представите, что у вас есть 4 якоря в вашем цикле, вы создаете 4 отдельные функции, которые можно визуализировать как ..

function() { alert(0); };
function() { alert(1); };
function() { alert(2); };
function() { alert(3); };

Я бы рассмотрел возможность изучения области видимости и замыканий с помощью javascript, как если бы вы пойти по этой дороге и не понимать, что именно происходит, вы можете столкнуться с серьезными проблемами из-за неожиданного поведения.

10
ответ дан 29 November 2019 в 06:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: