Подтвердить что ты не робот

Каков наилучший способ перебора элементов в javascript?

Недавно я пришел к другому способу петли, хотя массив в Javascript.

Я использовал для записи петли что-то вроде этого:

for (var len = 0; len < testData.length; len++) {
  total = total + testData[len];
}

Я прочитал код, который сделал это следующим образом:

for (var len = 0; testData[len]; len++) {
  total = total + testData[len];
}

Мне было интересно, как они будут работать, поэтому я нашел jsPerf, чтобы узнать это. Результаты довольно изумительны. Я ожидал, что второй метод будет немного быстрее, чем первый, но на самом деле намного, намного быстрее.

Есть ли здесь нисходящая сторона? Или это лучший способ перебрать элементы списка.

Update:

Состояние серого приближается, и Diode указал мне на простой недостаток в тестовом файле, который, по-видимому, был быстрее.

После исправления ошибки это самый быстрый:

var datalen = testData.length;
for (var len = 0; len <datalen; len++) {
     total = total + testData[len];
}

Обновление 2:

После тестирования в некоторых других браузерах этот тестовый тест снова принимает другое направление. Только в Chrome и Opera обычный для цикла самый быстрый. В других других браузерах путь Шмиддти только немного быстрее.

var i = testData.length, sum=0;
while (i--){
    sum += testData[i];
}
4b9b3361

Ответ 1

Вы также можете сделать такой цикл:

var i = testData.length;

while (i--){
    console.log(testData[i]);
}

Обратите внимание, что он перемещает массив назад.

Или, для суммирования:

var i = testData.length, sum=0;

while (i--){
    sum += testData[i];
}

Ответ 2

Я бы сказал, что первая форма лучше. Вторая форма имеет некоторые проблемы. Что делать, если у вас есть разреженный массив, содержащий значения falsy? Например: var testData = [ "text", undefined, false, 0, 5 ];

Я также ожидаю, что первая форма будет работать лучше. Особенно, если вы "кешируете" значение testData.length Так же:

var i, len = testData.length;
for (i = 0; i < len; i += 1) {
  total = total + testData[i];
}

Ответ 3


ОБНОВЛЕНИЕ: я был неправ, forEach очень медленный! Кажется, петли лучше


Вы должны использовать forEach, который определен в 5-м выпуске ECMAScript.

testData.forEach(function(val,i,arr){
    total += val;
});

Аргументы:

  • val - текущее значение
  • i - текущий индекс
  • arr - это массив

вам не нужно использовать все из них:

testData.forEach(function(val){
    total += val;
});

И для браузеров, которые его не поддерживают, эту прокладку можно использовать:

if(!Array.prototype.forEach){
    Array.prototype.forEach = function(fn, scope) {
        for(var i = 0, len = this.length; i < len; ++i) {
            fn.call(scope || this, this[i], i, this);
        }
    }
}

Подробнее см. Array.forEach.

Ответ 4

Основываясь на ответе Shmiddt, вы можете использовать цикл назад. кажется, что это немного быстрее, чем когда-либо назад в Firefox, а в Chrome они связаны:

var total = 0;
for (var len = testData.length-1; len >=0; len--) {
  total += testData[len];
}

Тест: http://jsperf.com/for-until-length-vs-until-undefined/10

Ответ 5

Что касается производительности, testData[len] просто проверяет, определен ли элемент, а не null/false/ "falsish", что быстрее, чем сравнение, и особенно получение testData.length для каждой итерации.

Итак, второй способ быстрее, но не более надежный - как правильно заявил Фритц ван Кампен.

Ответ 6

Ваш код установки вставляет 0, что заставляет цикл прерывать первое условие

var testData = [];
for (var i = 0; i < 1000; i++) {
  testData.push(i);  // pushes 0 to `testData`
}


for (var len = 0; testData[len]; len++) {   // loop breaks on first condition-check as testData[0] is 0.
  total = total + testData[len];
}

Измените установочный код, как показано ниже, и посмотрите разницу

var testData = [];
for (var i = 0; i < 1000; i++) {
  testData.push(i+1);
}

http://jsperf.com/for-until-length-vs-until-undefined/6