JavaScript-оператор for для непредсказуемых результатов - PullRequest
2 голосов
/ 11 января 2012

У меня есть следующий код:

var images = document.getElementsByTagName('img');

if (screen.width > 640) {
    for (var image in images) {
        image = images[image];

        console.log(image['src']);
    }
}

На странице только одно изображение, но по какой-то причине оператор for ... in циклически повторяет images три раза.Почему это так?

Пример: http://jsfiddle.net/OliverJAsh/C8egs/

Ответы [ 5 ]

7 голосов
/ 11 января 2012

Вы не просто просматриваете список элементов, но и называете методы:

  • length
  • item
  • namedItem

Правильный подход:

for (var i=0; i<images.length; i++) {
    var image = images[i];

    console.log(image['src']);
}

Вместо использования document.getElementsByTagName('img') вы также можете использовать document.images.

http://jsfiddle.net/C8egs/2/

5 голосов
/ 11 января 2012

for(var x in var) не должен использоваться для прохождения массива, так как он проходит через ключи в объекте.

Если вы делаете:

for (var image in images) {
        console.log(image );
}

Вы заметите, что вывод консоли будет отображать 'length' (как и любые другие свойства объекта);

Вместо этого используйте это как:

for (var i=0; i < images.length; i++) {
    var image = images[i];

    console.log(image['src']);
}
4 голосов
/ 11 января 2012

Проблема в вашей петле for..in.Цикл for..in перебирает все перечисляемые свойства объекта.getElementsByTagName возвращает NodeList.Все nodeList объекты имеют как минимум два дополнительных свойства, кроме найденных элементов: свойство length, содержащее количество найденных элементов, и свойство item, метод (в соответствии со спецификацией DOM) для числового доступа к элементам.1008 *

Если вы просматриваете массивоподобный объект, вы должны использовать вместо него простой for цикл:

for (var i = 0; i < images.length; i++) {
    console.log(images[i].src);
}
3 голосов
/ 11 января 2012

Цикл не три раза, фактически он повторяется четыре раза. Цикл отличается в разных браузерах. Я проверил это в IE8 и FireFox В FireFox он зацикливался четыре раза и вывод консоли

  • узел изображения
  • длина
  • пункт
  • namedItem

В IE8 он повторяется дважды

  • длина
  • позиция индекса тега img

Таким образом, вы должны исправить цикл for, как показано ниже

var images = document.getElementsByTagName('img');
if (screen.width > 640) {
    for (var i in images) {
        image2 = images[i];
        if(image2.nodeName == "IMG" || image2.nodeName == "img")
        console.log(image2['src']);
    }
}
1 голос
/ 11 января 2012

javascript for in выполняет итерацию свойства объекта, а не содержимого массива.попробуйте это:

var obj = {"name": "one", "date": 10, "help": false};

for (var key in obj) {
    alert(key);
} 

вы должны прибегнуть к итерации, получив доступ к индексу элемента в массиве.

for (var idx = 0, numImages = images.length; idx < numImages ; idx++) {
      image = images[idx];
      console.log(image['src']);      
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...