Почему списки узлов содержат дополнительные неопределенные элементы, которые не отражены в его свойстве длины? - PullRequest
2 голосов
/ 17 сентября 2011

Справочная информация:


Я столкнулся с очень странным явлением при работе со списком узлов.Я хотел использовать getElementsByClassName или что-то подобное, а затем отсортировать его.Я решил, что одним из способов будет перебирать нодлист, помещать каждый элемент в массив и сортировать массив.(Кстати, это сработало, но не так, как ожидалось).Я пытался использовать for (var i in nodeList) для итерации, но он выдавал исключение для последних нескольких элементов, которые не были определены.странная часть в том, что я мог бы вместо этого использовать for (var i = 0; i < nodeList.length; i++).Я только что проверил это снова и на странице stackoverflow я запустил в своей консоли следующий код:

for (var i in document.getElementsByTagName("span"))
    console.count("items");
console.log(document.getElementsByTagName("span").length);

Он отсчитал до items: 382, но длина дала 380.Как и ожидалось, когда я вошел в document.getElementsByTagName("span")[380] и document.getElementsByTagName("span")[381], они вернулись неопределенными.Это странное поведение не происходит в массивах (предоставлено, списки узлов и массивы различны, но это доказывает, что это не отличается для циклов, вызывающих проблему).

question:


Почему конструкции for(var i in nodeList) ведут себя по-разному в списках узлов, возвращая пару неопределенных элементов в конце?

Ответы [ 2 ]

3 голосов
/ 17 сентября 2011

Два дополнительных свойства, которые ловит оператор итерации for in:

  • длина
  • item

Позвольте мне привести простой пример,Скажем, на странице 3 элемента SPAN.

var spans = document.getElementsByTagName( 'span' );

Теперь spans - это NodeList объект, который содержит 5 свойств:

  • 0
  • 1
  • 2
  • длина
  • item

Первые 3 свойства являются индексамии они содержат ссылки на эти элементы SPAN.Два других свойства - длина и элемент - являются двумя дополнительными свойствами.Все объекты NodeList имеют эти два свойства.

Оператор for in выполняет итерации по всем 5 свойствам объекта NodeList , что, вероятно, не то, что вам нужно.Поэтому используйте обычный оператор for.

var i, span;

for ( i = 0; i < spans.length; i++ ) {
    span = spans[i];
    // do stuff with span
}
2 голосов
/ 17 сентября 2011

for-in перебирает всех перечисляемых свойств объекта, таких как длина и элемент (это ваша ситуация). Вот откуда пришли еще два результата. Также будет перечислено все, что добавлено к прототипу объекта.

для перебирает числовые индексы и не учитывает перечислимые свойства. Вот почему гораздо надежнее использовать прежний способ.

...