views:

25

answers:

1

Hey,

I use the following pattern in my JS:

var lib =
{
  module_one:
  {
      init: function () {
          ...
      }
  },
  module_two:
  {
      init: function () {
          ...
      }
  }
};

Question is, whats the best way to add:

(function ($) {          
  ...
})(jQuery);

I tried to put it around the var lib, but that didnt work. To add it inside each function worked, but seems a bit messy..?

Is it possible to add it to the init: function($) somehow?

Quite new on jQuery, so if you have any other suggestions around this pattern, let me know :-)

+1  A: 

Basically, you can do this:

(function() {
    var global, lib, oldlib;

    // We call this anonymous scoping function directly, so we know that
    // within it, `this` is the JavaScript global object. Grab a
    // local reference to it so we can use it within functions that get
    // called via dotted notation and so have different `this` values.
    global = this;

    // Remember any value that already exists for the `lib` property
    // of the global
    oldlib = global.lib;

    // Define our lib, assigning it to a local variable
    var lib = {
        /* ...your stuff as usual, plus: */

        noConflict: function() {
            global.lib = oldlib;
            return lib;
        }
    };

    // Publish our lib externally on the global object
    global.lib = lib;
})();

...which can then be used like this:

var alias = lib.noConflict();

Here's how that works:

  1. We define a scoping function and then immediately call it.
  2. Within the scoping function, we grab the this value as a variable called global. This will be the JavaScript global object because of the way we're calling the scoping function. (The global object on browsers is window, but there's no need to limit this to browsers, hence getting global this way).
  3. The first thing we do is save any old value the lib property of the global object had, in a local variable in our scoping function called oldlib.
  4. We set up our new value for lib.
  5. Our noConflict function restores the earlier value of the lib property, and returns our lib reference so someone can use it as an alias.

BTW, when you use a scoping function, you can also switch over to using named functions rather than anonymous ones, which has several benefits. Here's the above updated to use a named function for noConflict.

(function() {
    var global, lib, oldlib;

    // We call this anonymous scoping function directly, so we know that
    // within it, `this` is the JavaScript global object. Grab a
    // local reference to it so we can use it within functions that get
    // called via dotted notation and so have different `this` values.
    global = this;

    // Remember any value that already exists for the `lib` property
    // of the global
    oldlib = global.lib;

    // Define the functions for our lib. Because they're defined
    // within our scoping function, they're completely private
    function lib_noConflict() {
        global.lib = oldlib;
        return lib;
    }

    // Define our lib, publishing the functions we want to be public
    var lib = {
        /* ...your stuff as usual, plus: */

        noConflict: lib_noConflict
    };

    // Publish our lib externally on the global object
    global.lib = lib;
})();
T.J. Crowder