$.каждый() vs for () цикл-и производительность
это в основном просто некоторые вещи, которые мне было интересно, может быть, кто-то может дать мне немного больше информации о них, я поделюсь тем, что я заметил до сих пор!
Первое, что мне было интересно... есть ли какая-либо разница хорошая или причина для использования:
$('element').each(function (i, el) { });
-- против --
$.each($('element'), function (i, el) { });
глядя на документы jQuery, я не вижу никакой рифмы или причины для одного или другого (возможно, вы знаете экземпляр или дополнительные вещи одно может сделать над другим.
но что еще более важно меня беспокоит скорость здесь
// As opposed to $.each() looping through a jQuery object
// -- 8x faster
for (var i = 0, $('.whatever').length; i < len; i++) {
$('.whatever')[i] // do stuff
}
если вы проверите это jsFiddle демо здесь, вы увидите, что разница в скорости в основном эквивалентна с любым из них, но что еще более важно, я чувствую, что должен всегда использовать for() петли...
Я просто модульное тестирование (цикл через каждый из 5 различных сценариев функции, 50 000 раз), просто перебирая кучу элементов списка и устанавливая data-newAttr, ничего особенного.
вопрос:: я думаю, мой самый большой вопрос, почему бы и нет всегда использовать для циклов при итерации через объект?? Есть ли вообще смысл использовать $.каждый()? Вы всегда используете for () loops даже при прохождении объектов jQuery?
Function type: Execution Time:
_testArea.each() + $(this) 1947 <-- using $(this) slows it down tremendously
$.each() + $(this) 1940
_testArea.each() + el(plain JS) 458 <-- using the Element speeds things up
$.each() + el(plain JS) 452
for() loop + plainJS[0] iteration 236 <-- over 8x faster
только мои 2 цента. :)
6 ответов:
одно
.each()позволяет сделать это не может быть сделано сforцикл сцепление.$('.rows').each(function(i, el) { // do something with ALL the rows }).filter('.even').each(function(i, el) { // do something with the even rows });
Я играл с вашим JSFiddle чтобы увидеть, как цепочка будет влиять на производительность в тех случаях, когда вам нужно перебирать подмножества исходного набора согласованных элементов.
результат не был таким уж неожиданным, хотя я думаю, что накладные расходы
end()здесь было преувеличено из-за сочетания нескольких элементов и множества петель. Кроме этого: простые петли JS все еще немного быстрее, но весит ли это до добавленной читаемости.each()(и цепочка) является спорным.
одна вещь, которую вы получаете с
.each()является автоматической локальной областью (потому что вы вызываете анонимную функцию для каждого объекта), что в свою очередь означает, что если вы создаете еще больше анонимных функций/замыканий/обработчиков событий/что угодно на каждой итерации, вам никогда не придется беспокоиться о том, что ваши обработчики используют переменную. То есть JavaScript не действует как другие языки, когда речь заходит о локальных областях, но поскольку вы можете объявить переменную в любом месте, она может обмануть вас иногда.другими словами, это неправильно:
var idx,el; for (idx = 0; idx <someObjectArray.length; idx++){ el = someObjectArray[idx] el.someEventHandler(function(){ alert( "this is element " + idx); }); }всякий раз, когда какой-либо из этих объектов вызывает их "someEvent" после этого цикла (обратите внимание, что это составлено), предупреждение всегда будет говорить все, что было в последний раз назначено
idx, который должен быть (на момент вызова)someObjectArray.length;чтобы убедиться, что вы сохранили правильный индекс, вы должны объявить локальную область, создать переменную и назначить эту переменную для использования.
var idx,el; for (idx = 0; idx <someObjectArray.length; idx++){ el = someObjectArray[idx]; (function(){ var localidx = idx; el.someEventHandler(function(){ alert( "this is element " + localidx); }); })(); }как вы видите, это ужасно, но должно сработать. Каждый обработчик событий получает свою собственную копию
localidxтеперь сравните это с
.each()$(someObjectArray).each(function (idx, el) { el.someEventHandler(function(){ alert( "this is element " + idx); }); });много проще, не так ли?
jQuery.против каждого цикла
преимущества jQuery.каждый:
- хорошо вписывается в код jQuery (подключение и стиль).
- не беспокойтесь о области (ссылки на итератор и объект будут постоянными).
- может использоваться повсеместно (для всех видов объектов и итерации по ключам объектов).
преимущества цикла:
- высокая производительность (для игр/анимации/большие набор данных.)
- полный контроль над итератором (пропустить элементы, элементы соединения из списка и т. д.).
- for-loop всегда будет работать, так как нет никакой зависимости от jQuery.
- тот же знакомый синтаксис, что и большинство других подобных языков.
пример кода
это пример кода, как я предпочитаю перебирать список.
var list = ['a', 'b', 'c', 'd', 'e', 'f'];jQuery.каждый:
$.each(list, function(i, v) { // code... });For-loop без закрытие:
for(var i=0,v,n=list.length;i<n;i+=1) { v = list[i]; // code... }For-loop с закрытием:
for(var i=0,n=list.length;i<n;i+=1) { (function(i, v) { // code... })(i, list[i]); }примечание: Я предлагаю вам просто использовать стандартный for-loop, и использовать только закрытие, когда это необходимо. Однако, когда ваш код выглядит больше как jQuery, чем Javascript в любом случае, было бы проще просто использовать
$.each. В случае проблем с производительностью, вы всегда можете посмотреть на него позже.
когда я пошел по вашей ссылке вот два номера, которые я получил:
$.each() + el(plain JS) 401 for() loop + plainJS[0] iteration 377Если разница так мала, тогда идите с тем, который наиболее читаем, но, если у вас очень высокие требования к времени, вам может просто нужно пойти с тем, что в конечном итоге будет самым быстрым.
Я бы предложил вам написать свою программу, чтобы использовать три разных метода, два выше, а затем использовать foreach, найденный в более новых версиях javascript, и для тех браузеров, которые его не поддерживают, вы можете добавить его в качестве прототипа.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
вы знаете, каковы ваши требования, и что ваша программа будет делать, поэтому просто напишите свои собственные тесты и убедитесь, что он соответствует требованиям в браузерах, которые вы будете поддерживать.
для вашего первого вопроса, я бы пошел с
$('element').eachкак это гораздо легче читать, но это только мое мнение.
Я провел несколько простых тестов производительности в то время как назад http://jsperf.com/forloops3. кажется, что придерживаясь простой, старый
for loop(где это возможно) путь :)
на самом деле есть большая разница между $.каждый и.)($ каждый.)(
Они делают немного разные вещи в зависимости от того, что вы проходите.
http://api.jquery.com/each/ vs http://api.jquery.com/jquery.each/
jquery.каждый из них является универсальным итератором, где $().каждый () является специфичным для коллекции jquery.
Comments