Доступ вне переменной в цикле от закрытия JavaScript [дубликат]

Лучший способ создать каждый к не к.

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

36
задан Anurag 21 May 2010 в 08:03
поделиться

5 ответов

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

    for (var i in this.items) {
            var item = this.items[i];
            $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
            $("#showcasebutton_"+item.id).click( 
                // create an anonymous function that will scope "item"
                (function(item) {
                   // that returns our function 
                   return function() {
                    alert(item.id);
                    self.switchto(item.id);
                   };
                })(item) // immediately call it with "item"
            );
    }

Примечание: я вижу, что у вас здесь jQuery. У него есть вспомогательная функция $. Each () , которая может использоваться с массивами и может быть сокращением для простых циклов for / each. Из-за того, как область видимости работает в этом вызове - вам не нужно использовать замыкание, потому что "item" уже является параметром функции при ее вызове, а не хранится в var в области родительской функции. -А вроде было правдой в вашем примере.

$.each(this.items,function(i, item) {
  $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
  $("#showcasebutton_"+item.id).click(function() {
    alert(item.id);
    self.switchto(item.id);
  });
});
40
ответ дан 27 November 2019 в 06:09
поделиться

Другой способ приблизиться к этому - убедиться, что бизнес = items [i] эффективно выполняется путем вызова функции. Вкратце, это:

for (var i in this.items) {
    (function(item) {
        $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
        $("#showcasebutton_"+item.id).click(function() {
            alert(item.id);
            self.switchto(item.id);
        });
    })(this.items[i]);
}

Анонимная функция там немного запутана, поэтому для этой цели предпочтительнее иметь не очень анонимную, но она помогает.

4
ответ дан 27 November 2019 в 06:09
поделиться

Замыкания Javascript хранят ссылки на свои переменные, поэтому все ваши обработчики onclick используют одну и ту же переменную.

Вам нужно захватить переменную в промежуточной функции, например:

function buildClickHandler(pageNumber) {
    return function()  {    //Create and return a new function
        alert(item.id);
        self.switchto(item.id);
    }
}

Затем используйте эту функцию для создания щелкните обработчики, например:

1
ответ дан 27 November 2019 в 06:09
поделиться

попробуйте этот цикл

for (var i=0; i < this.items.length; i++) {
  this.items[i]
};
0
ответ дан 27 November 2019 в 06:09
поделиться

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

В новой версии библиотеки 1.4, они добавили функцию jQuery.proxy () . Это позволяет вам эффективно изменять контекст / область действия вызываемой функции - это делается способом jQuery, что гарантирует, что вы можете прекратить использовать методы, которые потенциально могут что-то испортить.

0
ответ дан 27 November 2019 в 06:09
поделиться
Другие вопросы по тегам:

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