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!
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.
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.
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).