Задать вопрос

JQuery parents().get(2) против parent().parent().parent()?

Помогите разобраться какой из методов правильнее и быстрее
  • Вопрос задан
  • 24110 просмотров
Подписаться 11 Оценить 1 комментарий
Решения вопроса 1
Smileek
@Smileek
Спасибо, веселенькая задачка получилась.:)
Тестим вот на этом:
<div id="i1"><div id="i2"><div id="i3"><div id="i4"></div></div></div></div>
<div id="info"></div>

Вот так:
var x, dt, dt2;
var iter = 100000;
dt = new Date();
for (var i = 0; i < iter; i++)
{
    x = $("#i4").parent().parent();
}
dt2 = new Date();
$("#info").text(dt2 - dt);
				
dt = new Date();
for (var i = 0; i < iter; i++)
{
    x = $("#i4").parents().get(2);
}
dt2 = new Date();
$("#info").text($("#info").text() + ":" + (dt2 - dt));

На заданном примере выигрывает parents().get(2). 3398:2910
Далее делаем 12 вложенных элементов и прогоняем пример из комментария — пять parent()-ов против parents().get(5): с огромным перевесом выигрывает get(5) — 5374:3954.
А вот get(3) проигрывает parent().parent().parent() — 3406:3880.

Получается, что выбрать все 12 элементов и в них найти третий, дольше, чем три раза прыгнуть вверх по дереву.

Наконец, вернемся к первому варианту с четырьмя элементами, и попробуем воспользоваться полученным родителем.
var x, dt, dt2;
var iter = 10000; /* <-- В 10 раз уменьшим, а то зависнем */
dt = new Date();
for (var i = 0; i < iter; i++)
{
   $("#i4").text($("#i4").parent().parent().attr("id")); /* <-- Запишем id родителя в текст потомка */
}
dt2 = new Date();
$("#info").text(dt2 - dt);
				
dt = new Date();
for (var i = 0; i < iter; i++)
{
   $("#i4").text($("#i4").parents().get(2).attr("id"));  /* <-- Попробуем сделать то же самое */
}
dt2 = new Date();
$("#info").text($("#info").text() + " " + (dt2 - dt));

И вот тут нас ждет сюрприз: $("#i4").parents().get(2).attr is not a function
arr.get(i), по сути, то же, что и arr[i], то есть мы получим просто Object.
Для того, чтобы воспользоваться jQuery-функциями, придется обернуть его в денежный знак:
$("#i4").text( $( $("#i4").parents().get(2) ).attr(«id»));
От этого мы и потеряем в производительности: 2665:2973.

Мораль:
1) Всегда найдутся варианты использования, которые лучше для одного варианта и хуже для другого.
2) Эффект от производительности или ее потери будет только на больших числах — в самом первом примере мы выиграли 0,4 секунды за 100000 (!) итераций.
3) Поэтому поступайте, как велит эстет внутри Вас: мне, скорее всего, в реальном примере было бы удобнее получить jQuery-объект и дважды воспользоваться parent()-ом. С другой стороны, восемь раз я бы писать parent() не стал: религия не позволяет.
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
Yngvie
@Yngvie
По поводу скорости не скажу, чисто визуально выбрал бы первый вариант из двух предложенных.

А в идеале использовал бы селектор в вызове parents
el.parents('.container')
el.parents('li')
Ответ написан
@magicstream Автор вопроса
вопрос каcается только эстетики кода и скорости.
правильно ли повторять parent() 3 раза или лучше получить результат с помощью разового вызова parents().
вопрос можно переформулировать для случая с 5 тым парентом:
parents().get(5) против parent().parent().parent().parent().parent()
Ответ написан
Комментировать
@magicstream Автор вопроса
Собственно сам вопрос появился при анализе кода индусов, очень часто встречается вариант с повторением parent(). И причем повторять могут и >10 раз.
Поначалу я осудил этот подход. Но по всей видимости их подход имеет право на жизнь.
Ответ написан
@frezerto
.closest();
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы