Итерация ассоциативного массива с помощью jQuery.each

Вероятно, самым важным фактором для этого вопроса является то, что я сейчас очень сонлив.

У меня есть массив, который я запускаю:

var cells = [];

Затем я поместил в него некоторые значения (объекты jQuery), например:

$("td").each(function () {
  var td = $(this);
  cells[td.attr("id")] = td;
});

А теперь моя проблема. Этот код:

$(cells).each(function (i) {
  console.log(this) // firebug console
});

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

cells[td.attr("id")] = td;

с

cells.push(td);

Он работал правильно.

Кроме того, когда я пытаюсь выполнить итерацию с циклом for..in, он работает так, как ожидалось.

for (var cell in cells) {
  console.log(cells[cell]);
}

Doeas означает, что метод jQuery.each не принимает ассоциативные массивы или я что-то не так делаю?

Ответы

Ответ 1

JavaScript не имеет ассоциативных массивов. У этого есть Массивы, и у него есть Объекты, а массивы - объекты. Когда вы это сделаете:

var a = [];
a['foo'] = 'bar';

.. вы фактически делаете эквивалент этого:

var a = [];
a.foo = 'bar';
// ^--- property of object 'a'

То есть вы фактически добавляете свойство foo к объекту a, не добавляя элемент в массив a.

Из документации для jQuery.each():

Массивы и подобные массиву объекты с свойством length (например, объект arguments) повторяются с помощью числового индекса от 0 до length-1. Другие объекты повторяются через их именованные свойства.

Поскольку вы создали Array ([]), jQuery просматривает его свойство length, и поскольку вы не добавили никаких элементов в массив (только свойства объекта, помните), его length по-прежнему нуль и поэтому jQuery (правильно) ничего не делает.

Вместо этого, как отмечали другие, вы хотите создать объект, используя, например, var cells = {};. Поскольку объект non-Array не имеет свойства length (но не по умолчанию, так или иначе), jQuery будет знать, что вы действительно хотите перебирать его свойства, а не числовые индексы, как в массиве.

Ответ 2

Вы, кажется, думаете, что массивы Javascript являются ассоциативными, что не так. Вероятно, вы ищете объекты (или хеши):

var cells = {};         // Not [].
$("td").each(function() {
    var td = $(this);
    cells[td.attr("id")] = td;
});

$.each(cells, function() {
    console.log(this);  // This should work as expected.
});

Ответ 3

используйте $.each(cells, function(i) { ... }) вместо $(cells).each(function...)

Функция $.each() отличается от $(selector).each.