2011-08-09 3 views
0

В следующем примере кода я получаю странное поведениеиндекс сумма в JavaScript Еогеасп

var data = ['xxx', 'yyy']; 
for (var i in data) 
{ 
    var a = i; 
    var b = data[i]; 
} 

двух первых итераций работает просто отлично. Я получаю индекс "0" и "1" в i, но затем он проходит одно дополнительное время, и теперь i - "sum". Это по дизайну или для чего используется эта дополнительная итерация? Результат в моем случае всегда пуст, и это испортит мой код. Есть ли способ не делать его дополнительный цикл?

BR Andreas

+0

Вы слишком упрощенно это. Как выглядит настоящий код? – cwallenpoole

+0

Нет, это не настоящий код, но проблема в этом случае одинакова. – Andreas

ответ

4

Вы зацикливания через Array, а не через Object. Для массивов лучше использовать:

for (var i=0; i<data.length; i=i+1){ 
    /* ... */ 
} 

В вашей петле учитываются все свойства объекта Array. Это делает цикл for ... in для массива менее предсказуемым. В вашем случае это выглядит как sum - свойство (метод), которое добавлено к Array.prototype в другом месте вашего кода.

Существует множество способов перебрать массивы. Смотрите, например this SO-question или this one

Просто для удовольствия, более эзотерический способ цикла массива:

Array.prototype.loop = function(fn){ 
    var t = this; 
    return (function loop(fn,i){ 
    return i ? loop(fn,i-1).concat(fn(t[i-1])) : []; 
    }(fn,t.length)); 
} 
//e.g. 
//add 1 to every value 
var a = [1,2,3,4,5].loop(function(val){return val+1;}); 
alert(a); //=> [2,3,4,5,6] 
//show every value in console 
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;}); 
+0

Итерация через 'for ... in', хотя она не является общей, по-прежнему является допустимым способом итерации по массиву. – cwallenpoole

+0

Вы верны в спецификации. В любом случае, он работает без сбоев в Firefox. – ghayes

+0

+1 для смещения -1 ... Использование 'in in 'массивов должно быть неодобрительно, и поэтому это хороший совет. На самом деле он не отвечает на вопрос о том, почему появляется переменная 'sum'. – nickf

6

Похоже, что вы (или какой-либо другой код, который вы включили) добавили дополнительные свойства на прототип массива. То, что вы должны делать это проверять, имеет ли объект вы итерация на самом деле это свойство на сам, а не на его прототип:

for (i in data) { 
    if (data.hasOwnProperty(i)) { 
     a = i; 
     b = data[i]; 
    } 
} 

Тем не менее, вы никогда не должны использовать for .. in на массивах. Используйте обычный цикл for.

Смотрите здесь для получения дополнительной информации: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

+0

Думаю, у вас это есть. Я буду утверждать, что есть еще одна библиотека, добавляющая Array.prototype.sum, создавая 'for ... in' iteration break. – cwallenpoole

+0

Из Википедии по этой теме: «Итерирует все используемые индексы массива, включая все определяемые пользователем свойства объекта массива, если таковые имеются. Таким образом, может быть лучше использовать традиционный для цикла с числовым индексом при итерации по массивам». – ghayes

1

Возможно, данные настройки, как это будет работать лучше: var data = {0:'xxx', 1:'yyy'};

1

Прежде всего data является объектом. Попробуйте добавить console.log (a); и console.log (b); внутри вашей петли, и вы увидите.

2

Вот способ безопасной итерации.

var data = ['xxx', 'yyy']; 
for (var i = 0; i < data.length; i++) 
{ 
    var a = i; 
    var b = data[i]; 
} 

Что вы получаете это метод исходя из расширения объекта Array, я думаю, вы используете какую-то библиотеку, где что-то вроде Array.prototype.sum = function() {...};

Смежные вопросы