0

I really like the JavaScript module pattern to encapsulate data and logic. I'm also using jQuery extensively. My question is this:

If I define a jQuery extension/plug-in WITHIN a module, will it be local to that module like other functions would be? (I suspect the answer is no...)

Example:

var igPartListManager = (function () {
    // Define a jQuery plug-in I'd like to be local to igPartListManager 
    (function ($) {
        $.fn.myExtension = function () {
            // Do something with this.each()...
        }
    })(jQuery);

    var doSomethingCore = function () {
        // Use my jQuery plug-in
        $("selector").myExtension();
    };

    return {
        doSomething
            : doSomethingCore
    };
})();

Outside of igPartListManager, would this succeed?

...
$("some_unrelated_selector").myExtension();

If it does, how do I best encapsulate 'local' jQuery-extension/plug-in-like functionality within a module?

n8wrl
  • 19,439
  • 4
  • 63
  • 103
  • variables are local to scope, not modules, but in this case the jQuery plugin is a function, and a function creates a new scope, so yes! However, $ is a global, so when using the right quotes in the selector, the plugin works. – adeneo Dec 31 '13 at 12:53

1 Answers1

1

To better explain this I made a little example of what actually happens when you define your extension:

(function ($) {
    // $ = window.jQuery;
    $.fn.myExtension = function () {
        // Do something with this.each()...
    }
})(window.jQuery); // Note window.jQuery is basically the same as just jQuery from your example code

Whenever you try to access a variable, the javascript engine bubbles up trough all encapsulating scopes all the way up to the window scope. The first scope that has that variable is the scope that is being used. Since in your case the window scope holds your jQuery variable you could call it 'global'.

When calling this $("some_unrelated_selector).myExtension(); the engine looks for the variable $. If this variable points to window.jQuery at that point, you are in fact using the same object as before. So yes, that would succeed in that case. But only if you executed the igPartListManager function before trying to call $().myExtension();.

The only way to create a local scope for your extensions is to deep copy the window.jQuery variable to a local variable before adding extensions to it.

Example: Javascript deep copying object

Community
  • 1
  • 1
Hless
  • 3,326
  • 20
  • 22
  • Thank you @Hless. I am re-thinking my requirements here because I am not sure I'll be using the jQuery extension enough within my module to justify my own 'deep copy' of jQuery. Thank you so much! – n8wrl Dec 31 '13 at 13:16
  • Yeah, I think adding functions to `$.fn` of the global object is your best bet at this point. The jQuery class does get heavier, but I don't think having a complete copy of that class does you any good, performance wise. It's practically the same as loading the jQuery source code multiple times, using different variable names each time. – Hless Dec 31 '13 at 13:24
  • And yet the functions I want are LOCAL to my module, so adding them to the global $.fn is leakage I don't want. No one else will want these functions. – n8wrl Dec 31 '13 at 14:05