Pablo
Pablo

Reputation: 6058

jQuery plugin Private functions inside Vs. Outside the each loop

What is the difference between including private functions in a jQuery plugin in the examples below:

Outside the loop:

    (function( $ ){
      var defaults = {};

      $.fn.cmFlex = function(opts) {

        this.each(function() {
            var $this = $(this);
            //Element specific options
            var o = $.extend({}, defaults, opts);

            //Code here
        });

        function f1(){....
        function f3(){....
        function f2(){....

      };
    })( jQuery );

Inside the loop:

    (function( $ ){
      var defaults = {};

      $.fn.cmFlex = function(opts) {

        this.each(function() {
            var $this = $(this);
            //Element specific options
            var o = $.extend({}, defaults, opts);

            function f1(){....
            function f3(){....
            function f2(){....
        });     


      };
    })( jQuery );

The advantage of including the functions in the loop is that i will be able to access the $this variable as well as the Element specific options from f1() f2() f3(), are there any disadvantages to this?

Upvotes: 3

Views: 11541

Answers (4)

ezpn
ezpn

Reputation: 1748

If you don't want to redeclare methods every time loop function runs and still have access to $this variable, you may try to move functions outside and call them using call method.

(function( $ ){
  var defaults = {};

  $.fn.cmFlex = function(opts) {
    function f1(){}
    function f3(){}
    function f2(){}

    this.each((function() {

        return function() {
          var $this = $(this);
          //Element specific options
          var o = $.extend({}, defaults, opts);
          f1.call($this);
          f2.call($this);
          f3.call($this);
        };
    })());
  };
})( jQuery );

Upvotes: 0

Pablo
Pablo

Reputation: 6058

I ended up not using a jQuery plugin at all and encapsulation all the code inside the callback function for the $.getJSON call.

Here is an example

            $.getJSON('core/cm_json.php', function(options) {
                //Globals
                var defaults = options;

                //Where query is a jQuery query string
                function initialize(query){
                    $(query).each(function(){
                        var $this = this;

                        //Code here

                        function f1(){...
                        function f2(){...
                        function f3(){...
                    })
                }
            });

Upvotes: 0

Ruan Mendes
Ruan Mendes

Reputation: 92304

Always follow the concept of giving the least privilege to all your code. If no other code needs to reference those functions, there's no need to define them outside and changing those functions is simpler since you are guaranteed that they are not used anywhere else but within the loop.

If f1,f2,f3 needed access to closure variables within the looping function, they'd have to be defined in the function no matter what.

However there's a caveat. Defining them within a function requires creating a new closure every time the loop function is run. Depending on how tight the loop is, it could affect performance. My point is: premature optimization is bad, but keep it in mind.

FYI: Here's another way to do it (if you don't need the closure variables) that avoids creating the closures for every iteration of the loop. It looks a bit complex, so it's not for the faint of heart

(function( $ ){
  var defaults = {};

  $.fn.cmFlex = function(opts) {

    this.each((function() {
        function f1(){}
        function f3(){}
        function f2(){}
        // This is the method that will be called for each iteration of the loop. It now
        // has access to f1,f2,f3 but doesn't need to create a closure for each iteration.  
        return function() {
          var $this = $(this);
          //Element specific options
          var o = $.extend({}, defaults, opts);
          f1();
          f2();
          f3();
        };
    })());
  };
})( jQuery );

Upvotes: 9

casperOne
casperOne

Reputation: 74540

Depending on what you are trying to acheive, there could be; if you need to change the functions down the line so that f1(), f2() or f3() require things outside of that scope, then you have to deal with that migration.

However, from an encapsulation standpoint, this is preferable, as those functions will only be accessible from within that scope, making sure there is no "leakage".

Upvotes: 0

Related Questions