Должна ли конструкция Javascript "for in" повторять свойство length? - PullRequest
0 голосов
/ 24 марта 2010

Я делаю букмарклет, но я столкнулся с некоторым странным поведением в IE8. Код, вызывающий проблему:

var els = document.getElementById("my_id").getElementsByTagName("*");
for(var i in els)
{
    alert(i+","+els[i])
}

Первое, что предупреждает, это "длина, n". Это не относится к Chrome: только в IE8.

Интересно, что, похоже, он ведет себя по-разному в зависимости от того, идет ли код в консоли / адресной строке или на самой странице.

Это стандартное поведение?

EDIT:

Не до сайта, на котором я его запускаю. Возможно ли, что getElementsByTagName возвращает массив с ключом "length", установленным в IE? Это, конечно, не возвращает чистый массив.

Ответы [ 6 ]

3 голосов
/ 24 марта 2010

То, что вы получаете, это не массив, это nodeList. См. здесь , нажмите ссылку "getElementsByTagName ('element_name')"

Кроме того, for..in в любом случае не предназначен для итерации по массиву. Используйте

var item;
for (var idx=0, len=arr.length; idx<len; ++idx) {
  item = arr[idx];
  // whatever
}

для итерации массива.

Для нодлиста вы можете получить элемент с

list.item(idx); // where list is what you got from getElementsByTagName

если вы хотите сделать это "правильно".

2 голосов
/ 24 марта 2010

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

getElementsByTagName возвращает NodeList, а свойства NodeList указаны в стандарте DOM : length и item(i). Большинство реализаций JavaScript также позволяют [i].

Поэтому вы должны написать следующее:

var els = document.getElementById("my_id").getElementsByTagName("*");
for (var i = 0;i < els.length;i++)
{
    alert(i+","+els.item(i));
}
1 голос
/ 24 марта 2010

Вот как я перебираю списки. Таким образом, вам не нужно будет писать дополнительную строку в цикле, например var el = els[i].

var els = document.getElementById("my_id").getElementsByTagName("*");
for (var i=0, el; el=els[i]; i++) {
    // do what you like here
}
1 голос
/ 24 марта 2010

Не используйте for..in для чего-либо, кроме перечисления свойств объекта (если вы не любите сюрпризы!). Просто используйте простой цикл for для массивов и списков узлов.

0 голосов
/ 24 марта 2010

Часто используется метод для преобразования объекта, такого как список узлов, объект аргументов или пользовательский объект, в массив его членов.

Array.from= function(what){
 var L, A= [];
 if(!what) what= {};
 L= what.length;
 if(typeof L== 'number'){
  while(L) A[--L]= what[L];
  return A;
 }
 for(var p in what){
  if(what.hasOwnProperty(p)) A[A.length]= what[p];
 }
 return A;
}

var N=Array.from(document.getElementById("my_id").getElementsByTagName("*"))
while(N.length){
tem=N.shift();
}
0 голосов
/ 24 марта 2010

Нет, если вы не определите свой собственный итератор для NodeList s, который только для JavaScript (Mozilla). [Вот реализация] того, который я создал для своего репозитория js-iterators.

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