7

When would I use jQuery's .find()?

For example,

$('tr').find('.someClass'); is equivalent to $('tr .someClass')

So, when would be a good example of when you would use .find() over a straight selector?

Also, which is more performant? Is a selector quicker than .find()?

Kyle Muir
  • 3,875
  • 2
  • 22
  • 27
  • `.find()` is quicker than a selector actually. The jQuery parser has to work harder with selectors with multiple parts than selecting some elements and than filtering through them. – Sethen Oct 09 '13 at 20:53
  • Relevant: http://stackoverflow.com/q/6230266/139010 – Matt Ball Oct 09 '13 at 20:56

4 Answers4

5

The answer is whenever possible.

It is always more performant than having children / multi-item / CSS / context selectors, and is the fastest-performing traversing mechanism.

jsPerf to show what I mean.

The only time you may even consider not using it is if you only want to select items that are direct children, and those children happen to have the same class as their children that you don't want to select. This is a job for .children(), but is a very rare case.

PlantTheIdea
  • 16,061
  • 5
  • 35
  • 40
  • Cool, thank you very much for that. One additional question would be, is there a difference if you have `$('.someClass', containingElement)`? Or is `.find()` still much quicker? – Kyle Muir Oct 09 '13 at 21:01
  • 1
    @KyleMuir the former is turned directly into the latter. – Matt Ball Oct 09 '13 at 21:02
  • @MattBall Cool, thanks for that. I am now far clearer on the whole situation :) – Kyle Muir Oct 09 '13 at 21:05
  • Unless you're targeting IE8 apparently, :p – Kevin B Oct 09 '13 at 21:08
  • 1
    Unless I've screwed something up here, this less simplified perf seems to show the opposite http://jsperf.com/jquery-child-selector-vs-find/4 Shouldn't anything which can be run through `querySelectorAll` be faster than `find` on a non-trivial document? – James Montagne Oct 09 '13 at 21:08
  • That shows the fact that jQuery does implicit iteration. For each element found by the first selector, it performs a .find. Since the original jsperf only has one element selected by the initial selector, .find wins out. using just a selector skips that iteration completely and lets the css selector engine do the work. – Kevin B Oct 09 '13 at 21:13
  • 2
    @KevinB Exactly. In the original question, I can only assume that there is more than one `tr` on the page. `find` would likely be slower. – James Montagne Oct 09 '13 at 21:14
5

It depends on what you're selecting.

As the number of elements selected by $('tr') goes up, .find will become more expensive.

Generally it's best to do whatever will result in touching the least number of elements. When you're dealing with just 2 elements (a parent and a child), the .find will clearly be faster because it's just one parent getting it's children and filtering to a selector. But when there are, say, 200 parents, it's going to have to iterate over all 200 and search for children within each. By using a selector to begin with, you never touch all of the parents, you just go directly to the child elements. Even then, the performance of one vs the other will differ from browser to browser.

spend less time worrying about these micro optimizations until it's a real problem you are trying to solve, and at that point, solve that one problem rather than trying to figure out a general rule to follow.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • thanks for that, definitely agree on not worry about micro optimizations, this particular question was purely academic. Someone at work asked me the difference between them and I was curious as I didn't know myself. – Kyle Muir Oct 09 '13 at 21:30
1

.find() is simply for searching for descendants of a jQuery object that represents a DOM element.

An example use case would be passing a jQuery object that represents a form element into a form parsing function, and then using .find() to grab different values from the form's child inputs.

Instead of converting the form into a jQuery object every time you want to grab an element, it's cheaper to assign the jQuery form object to a variable, and then use .find() to grab the inputs.

In code, this:

var $form = $('#myFormId'),
    firstName = $form.find('input[name="firstName"]').val(),
    lastName = $form.find('input[name="lastName"]').val();

is cheaper then this:

var firstName = $('#myFormId input[name="firstName"]').val(),
    lastName = $('#myFormId input[name="lastName"]').val();

It's also cheaper then using .children(), see this reference, unless the items you are searching for direct children of the jQuery object you are operating on.

Hopefully that makes sense :)

Patrick Coffey
  • 1,073
  • 8
  • 13
0

Great answers above, but just wanted to add .find() is a descendant based search. So it will find all the children of the Dom element being selected.

JeremyS
  • 427
  • 2
  • 7