проблема области видимости JavaScript, когда лямбда-функция ссылается на переменную в замкнутом цикле - PullRequest
7 голосов
/ 13 мая 2010

Первый вопрос по stackoverflow :) Надеюсь, я не смущаюсь ...

У меня есть функция javascript, которая загружает список альбомов, а затем создает элемент списка для каждого альбома. Элемент списка должен быть кликабельным, поэтому я вызываю jQuery click () с функцией, которая делает вещи. Я делаю это в цикле. Моя проблема в том, что все элементы, похоже, получают одну и ту же функцию щелчка, хотя я пытаюсь создать новую, которая будет выполнять разные вещи в каждой итерации. Другая возможность состоит в том, что итерационная переменная каким-то образом является глобальной, и функция ссылается на нее. Код ниже. debug () - это просто инкапсуляция консоли Firebug.debug ().

function processAlbumList(data, c) {
 for (var album in data) {
  var newAlbum = $('<li class="albumLoader">' + data[album].title + '</li>').clone();
  var clickAlbum = function() {
   debug("contents: " + album);
  };
  debug("Album: " + album + "/" + data[album].title);
  $('.albumlist').append(newAlbum);
  $(newAlbum).click(clickAlbum);
 }
}

Вот расшифровка того, что она печатает при запуске вышеупомянутой функции, после чего появляются строки отладки, вызванные тем, что я нажимаю на разные элементы. Всегда печатается «10», что является последним значением, которое принимает переменная альбома (есть 10 альбомов).

Album: 0/Live on radio.electro-music.com
Album: 1/Doodles
Album: 2/Misc Stuff
Album: 3/Drawer Collection
Album: 4/Misc Electronic Stuff
Album: 5/Odds & Ends
Album: 6/Tumbler
Album: 7/Bakelit 32
Album: 8/Film
Album: 9/Bakelit
Album: 10/Slow Zoom/Atomic Heart
contents: 10
contents: 10
contents: 10
contents: 10
contents: 10

Есть идеи? Это ведет меня вверх по стене. :)

/ Стефан

Ответы [ 2 ]

8 голосов
/ 13 мая 2010

Вам необходимо ввести другую область видимости, например, такую:

var clickAlbum = (function (a) {
    return function () {
        debug("contents: " + a)
    };
})(album);
0 голосов
/ 13 мая 2010

Переменная album во внутренней функции является замыканием, однако ее значение не ограничено при объявлении каждой функции. Это означает, что каждый раз в цикле замыкание album будет изменяться на значение, которое оно имеет в этом цикле. Более подробное объяснение здесь

Как предполагает Шон (и статья), вы можете решить эту проблему, изменив область действия переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...