Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning jQuery function to variable doesn't work, but wrapping it does

I have some jQuery code that, depending on circumstances, should either look at the entire page, or else only within a certain part of it. So I originally had some code like this:

var doSearching = wholePage ? $ : $('#portion').find;
var target = doSearching('#someSelector');

After some debugging, I realized this was a problem, and taking an educated guess ended up with something along these lines:

var doSearching = $;
if (!wholePage)
  {
    doSearching = function(selector) {return $('#portion').find(selector);}
  }
var target = doSearching('#someSelector');

Well, that works OK, but I don't really understand what's going on that the first snippet is wrong but the second is correct.

What's happening?

like image 697
Casey Avatar asked Feb 13 '26 01:02

Casey


1 Answers

What's going wrong is that find relies on the value of this during the call to find (to know what it's looking within), but in your code, you're calling it directly, and so this during the call will be the global object (in loose mode) or undefined (in strict mode), not the jQuery instance that find expects it to be.

You could do this:

var portion = wholePage ? null : $('#portion'); // Or: `var portion = wholePage && $('#portion');` if you like
var doSearching = portion ? portion.find.bind(portion) : $;
var target = doSearching('#someSelector');

That uses Function#bind to ensure that when you call doSearching, find is called with this referring to the jQuery object resulting from $('#portion'), and so it knows what to search within.

It's basically a slightly more concise form of your "wrapping" example, but passes through all arguments rather than just one.


Function#bind is an ES5 feature missing on old browsers like IE8, but can be polyfilled if supporting them is important.

like image 125
T.J. Crowder Avatar answered Feb 15 '26 13:02

T.J. Crowder