I've been developing jQuery plugins for quite some time now, and I like to think I know how to design one well by now. One issue keeps nagging me though, and that is how to deal with private functions in a powerful yet elegant manner.

Now my question is: how to neatly DRY up that shared functionality? An obvious solution would be to put it in a function within the plugin's namespace:

var fill = function($obj, color) {

$obj.css('background-color', color);

};

Although this solution is effective and nicely namespaced, I really dislike it. For one simple reason: I have to pass it the jQuery object. I.e. I have to call it like this: ```fill(this, 'red');```, while I would like to call it like this: ```this.fill('red');```

Of course we could achieve this result by simply putting ```fill``` into ```jQuery.fn```. But that feels very uncomfortable. Imagine having ten plugins developed based on this approach and each plugin putting five of those 'private' functions into the jQuery function namespace. It ends up in a big mess. We could mitigate by prefixing each of these functions with the name of the plugin they belong to, but that doesn't really make it more attractive. These functions are supposed to be private to the plugin, so we do not want to expose them to the outside world at all (at least not directly).

So there's my question: does anyone of you have suggestions for how to get the best of both worlds. That is; plugin code being able to call 'private' plugin functions in a way similar to ```this.fill('red')``` (or ```this.myplugin.fill('red')``` or even ```this.myplugin().fill('red')``` etc.), while preventing jQuery function namespace pollution. And of course it should be light-weight, as these private functions might be called very frequently.

Replies(4)

You can use the .call() or .apply() methods of the Function object to do fill.call($obj,"red"), and then "this" will be the $obj when the function is run. This still requires you to pass the scope in at some point, however.

You may be having trouble with these private methods in plugins like this because of the simple fact that you have multiple public methods in your plugin. If you follow the old adage about "only taking one name in the jquery namespace" and created an interface by which the user can manipulate the plugin through that one public method (a la jQuery UI), then when you used private methods in that single public method, you'd be able to access the context of the public method straight away.

Without adding the function to $.fn, you can't call the function on a jQuery object like $obj.foo(); If you don't want to unify your plugin to claim a single public method, I'd say you should stick with the pseudo private approach you have and forget about setting the "this" of the private method. I say "pseudo-private" because your function isn't really private to anything but the closure you created to execute the plugin methods. In my experience with private methods in JavaScript, they're able to do most of their work by virtue of the arguments that they're passed and the other variables which they can access by virtue of being in an inner scope

I realise this plugin is completely useless, but the point is to illustrate that the private function "massage" is able to do all its work not by the arguments it receives nor its context, but because of the outer scopes that it can access.

In the last plugin I wrote, I made all of my methods private, simply functions prefaced with an _underscore. I then made these functions accessible through an interface object named methods {} If a string was passed to the plugin, it would attempt to call the public methods via the method handle.

Here's a simple example:

//initialization, etc

function _secret(x) {

//cool stuff

}

var method = {

gossip: function(x) {

//do some stuff

return _secret.call(this, x);

}

return this.each(function() {

if(typeof command == "string") {//execute public methods if called

var execute = method[command];

execute.call(this, callback);

}

else {

//rest of plugin

Now, the private methods may be called by the plugin internally, but some of them may also have a public interface.