Find the jQuery Bug #2: Point of No Return
25 Jan 2012Introduction
In this open-ended series Iโll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.
You can view my other post in this series...
The Desired Feature
We want to take the following HTML unordered list and build a JavaScript function that will determine if a specific value is present.
The Buggy Code
The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?
You can view, run, and edit the above code sample from JSBin.
The results that we expected were false, true, true, true, false
, but instead the output in the console is false, false, false, false, false
.
The Underlying Problem
At the root of the problem is the special jQuery .each()
method we are using. The .each()
method is a very handy way to iterate over the jQuery collection, however there is a special meaning to return false
within a .each()
method.
"We can stop the loop from within the callback function by returning false." --http://api.jquery.com/each
Upon further examination of the code it even makes further sense why it wouldnโt work. Most of us are familiar that a return
statement exists the current function, but in this case we arenโt invoking the functionโฆ jQuery is! So, jQuery has control over what happens when you exit your function prematurely and it recognizes return false
to mean something special.
A Solution
The solution to fix this problem is really simple and straightforward. All you really need to do is to introduce another variable hasNumber
. If the number was found, then set the hasNumber
variable to true
and then return false;
to exit the .each()
method.
You can view, run, and edit the above code sample from JSBin.
If you test out the code again below youโll notice that now that we are getting the expected output of false, true, true, true, false
.
An Alternate Solution
An alternate way to solve this problem would be to use another technique completely. In the following example we will use the jQuery.grep
method. The jQuery.grep
method is defined as the following:
"Finds the elements of an array which satisfy a filter function. The original array is not affected." --http://api.jquery.com/jquery.grep/
You can view, run, and edit the above code sample from JSBin.
Although the code looks shorter, it is less performant than the previous solution. Can you tell why? The code is not exiting once the number has been found, but instead goes through each array item and executes the callback function. We get the correct answer, but for a price.
Conclusion
The key concept to remember here is to be aware of the special mean of return false;
inside of a jQuery .each()
method to exit the loop. Even if you have never made this mistake before, maybe it has opened up your eyes to the fact you can exit out of a .each()
method!
Until next timeโฆ