1
\$\begingroup\$

I'm trying to learn learning javascript and jQuery plugin standards, and after some googling and testing I've come up with this pattern:

;(function(window, document, $, undefined){
  var plugin = function(element){
    var instance = this,
        somePrivateFunc = function(){
          console.log(instance.options);
        };

    this.options = $(element).data();
    this.publicFunc = function(){     
     somePrivateFunc();
    };
  }

  $.fn.myplugin = function(){
    return this.each(function(){
      if(!$(this).data('_myplugin')){
        var myplugin = new plugin(this);
        myplugin.publicFunc();
        $(this).data('_myplugin', myplugin);
      }
    });     
  }

}(window, document, jQuery));

Example

http://jsfiddle.net/4NAXb/

Is this OK? Do you have any suggestions on improving it? Thanks!

\$\endgroup\$
  • \$\begingroup\$ I suggest you take a look at jQuery Boilerplate. \$\endgroup\$ – Joseph Jun 9 '13 at 16:46
  • \$\begingroup\$ What is the leading ; for? \$\endgroup\$ – svick Jun 9 '13 at 17:24
  • \$\begingroup\$ idk.. i've just seen ppl do it :s \$\endgroup\$ – Alex Jun 9 '13 at 18:41
  • 1
    \$\begingroup\$ @svick It's explaned on the boilerplate: The semi-colon before function invocation is a safety net against concatenated scripts and/or other plugins which may not be closed properly. \$\endgroup\$ – Joseph Jun 9 '13 at 18:50
2
\$\begingroup\$

Here are some suggestions:

  1. Use $.data(this, '_myplugin') & $.data(this, '_myplugin', myplugin). They're SO MUCH faster.

  2. Since you call .publicFunc every time you instantiate your plugin, you should probably move the call into your constructor instead.

  3. Public functions should be assigned to the prototype, so that we don't create a new function every time we create a new instance.

  4. Likewise, define a private function outside of the constructor, in the parent closure. Again, we don't want to have to re-create the same function over and over again.

;(function ( window, document, $ ) {

  function somePrivateFunc ( instance ) {
    console.log( instance.options );
  }

  var Plugin = function( element ) {
    // What is this?
    this.options = $(element).data();
    this.publicFunc();
  }

  Plugin.prototype.publicFunc = function () {     
   somePrivateFunc( this );
  };

  $.fn.myplugin = function () {
    return this.each(function () {
      if ( ! $.data(this, '_myplugin') ) {
        $.data( this, '_myplugin', new Plugin(this) );
      }
    });     
  };

}(window, document, jQuery));

P.S. You haven't described how you're exposing the plugin's additional methods. For that you should read the jQuery plugin creation tutorial.

Find the section titled Provide Public Access to Secondary Functions as Applicable.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.