4

This snippet of code will return an element from a cache if it has been selected previously or select, cache, and return the element. It is useful for updating contents of elements which are never significantly changed (i.e, the parent of a counter seen by the user where the number changes but the parent does not). The code is as follows:

var $$ = (function() {
    var cache = {};
    return (function (selector) {
        return cache[selector] || ( cache[selector] = jQuery (selector) );
    });
})();

You can use it like so:

$$('#id')


Now... how the heck does this work? How does $$ have access to jQuery selector? It has nothing to do with $$ starting with $, you could just as well do var foo. How does $$ map what is passed into it to selector. I would expect to see var selector = argumentName inside of $$. Also, to me it does not appear that $$ is setup to receive arguments (e.g., function(input){} ) but it readily does?

This small piece of code is incredibly confusing to me and some clarity would be greatly appreciated. Thanks!

3
  • Here? jQuery(selector). It's just using a closure to keep the cache in memory so it can look up the selector before querying the DOM. Commented Sep 1, 2013 at 2:20
  • Yeah, I understand that, but how does the name selector map to whatever you pass in $$? On first run of $$('div') if you put in a debugger before return cache[selector] || ( cache[selector] = jQuery (selector) ); selector = 'div', how is that possible? Commented Sep 1, 2013 at 2:24
  • 1
    @JoshRobinson: because there are two functions in the code. The first function, the one without any arguments, gets called immediately (notice the (); at the very end of the code snippet) and returns the second function, which is the one that takes selector as an argument. Commented Sep 1, 2013 at 2:40

2 Answers 2

5

It's pretty straightforward. Here is the equivalent code but in an unpacked version to make it more explicit:

function generateCachingJQuery() {
    var cache = {};
    function queryFunc(selector) {
        if (cache[selector]) {
            return cache[selector];
        } 
        else {
            cache[selector] = jQuery(selector); //same as $(selector)
            return cache[selector];
        }
    }
    return queryFunc;
}
var $$ = generateCachingJQuery();

If you notice, first you have an anonymous function - which I named generateCachingJQuery here - which returns the function that $$ ends up being. This is done so that nothing but the internal function (named queryFunc here) has access to the cache variable. The rest is just a one-liner which I unpacked here to make it more clear what it's doing.

EDIT: To be clear, $$ ends up being queryFunc in the above code, not generateCachingJQuery. Notice that queryFunc takes selector as a variable.

Sign up to request clarification or add additional context in comments.

Comments

3
var $$ = (function() { // begin closure

  var cache = {}; // keep in memory through closure

  // The function that gets assigned to `$$`     
  return function(selector) {
    // If the element has already been queried (exists in the cache)
    // then return the element that was previously stored,
    // otherwise query the new element, add it to the cache and return it
    return cache[selector] || (cache[selector] = jQuery(selector));
  };
})(); // end closure

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.