Marcus
Marcus

Reputation: 67

jQuery Plugin Shared Functions and Variables

I am working on a jQuery plugin and am a bit confused on sharing functions and variables between methods within the same namespace. I know that the following will work:

    (function($){

    var k = 0;
    var sharedFunction = function(){
                //...
                }

    var methods = {

    init : function() { 
      return this.each(function() {
          sharedFunction();
        });
    },

     method2 : function() { 
      return this.each(function() {
          sharedFunction();
        });
    }
  };

$.fn.myPlugin = function(method) {
    // Method calling logic
    if (methods[method]) {
      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || ! method){
      return methods.init.apply(this, arguments);
    } else {
      $.error('Method ' +  method + ' does not exist here');
    }    
  };

})(jQuery);

However, I am wondering if there's a better way to do this. While I understand that the variable "k" and the function "sharedFunction" are not technically global (in that they cannot be accessed directly outside of the plugin), this seems unsophisticated at best.

I know that $.data is an option, but if you have a great deal of variables and functions that need to be accessed by multiple methods in the plugin, this seems like it could turn into a tremendous mess.

Any insights would be appreciated. Thanks!

Upvotes: 2

Views: 1185

Answers (1)

Richard Neil Ilagan
Richard Neil Ilagan

Reputation: 14747

One of the (arguably) more common pitfalls in Javascript is that { } do not define scope as other C-style languages; functions do.

With that in mind, save for making your variables global, there are two ways (I generally use) to share variables between two separate functions:

Declare the functions inside a common function

This is what you're demonstrating above. You're declaring your two functions inside another function (which defines the scope). Anything declared in child-level of the container function is available anywhere in its scope, including the scopes of your two inner functions.

// this is a self-calling function
(function () {

    var foo;

    var f1 = function () {
        // foo will be accessible here
    },

    f2 = function () {
        // ... and foo is accessible here as well
    }

})();

Honestly, this isn't "unsophisticated" at all, and is commonly done in lieu of not being able to define scope other than function scope in Javascript.

Namespacing common members

You can define an object in global scope, and then just extend that with your variables / functions. You do have to go global, but you're minimizing your footprint by ensuring that you only do it once.

window.app = {
    foo : 'bar'
};

(function () {

    var f1 = function () {
        // app.foo will be accessible here
    };

})();

(function () {

    var f2 = function () {
        // ... and here as well, even though we're 
        // in a totally different (parent) scope
    };

})();

Using $().data() may seem viable, but while it definitely has its uses, I somehow can't recommend tacking on that additional overhead for providing the functionality you describe when it can be as easily (and natively) achieved by simple language mechanics (albeit, readability takes a bit of getting used to).

Upvotes: 1

Related Questions