safetycopy
safetycopy

Reputation: 554

How do I scope variables properly in jQuery?

I'm working on a jQuery plugin, but am having some trouble getting my variables properly scoped. Here's an example from my code:

(function($) {

$.fn.ksana = function(userOptions) {
    var o = $.extend({}, $.fn.ksana.defaultOptions, userOptions);

    return this.each(function() {
        alert(rotate()); // o is not defined
    });
};

function rotate() {
    return Math.round(o.negRot + (Math.random() * (o.posRot - o.negRot)));
};

$.fn.ksana.defaultOptions = {
    negRot: -20,
    posRot: 20
};

})(jQuery);

I'm trying to get the private function rotate to be able to see the o variable, but it just keeps alerting 'o is not defined'. I'm not sure what I'm doing wrong.

Upvotes: 1

Views: 3973

Answers (3)

mthurlin
mthurlin

Reputation: 27285

You can either put the rotate-function in the same scope as o:

(function($) {

$.fn.ksana = function(userOptions) {
    var o = $.extend({}, $.fn.ksana.defaultOptions, userOptions);

    function rotate() {
        return Math.round(o.negRot + (Math.random() * (o.posRot - o.negRot)));
    };

    return this.each(function() {
        alert(rotate()); 
    });
};

Or, simply pass it to rotate:

(function($) {

    var o;
    $.fn.ksana = function(userOptions) {
        o = $.extend({}, $.fn.ksana.defaultOptions, userOptions);

        return this.each(function() {
           alert(rotate(o)); 
        });
    };

function rotate(o) {
    return Math.round(o.negRot + (Math.random() * (o.posRot - o.negRot)));
};

Upvotes: 2

Fyodor Soikin
Fyodor Soikin

Reputation: 80734

You have to put o in the scope that is surrounding for both rotate and ksana - i.e. in your root function($) scope. Like this:

(function($) {

var o;

$.fn.ksana = function(userOptions) {
   o = $.extend({}, $.fn.ksana.defaultOptions, userOptions);

But why don't you just make it an argument of rotate? Why do you need to make it kind of "global"?

Upvotes: 2

Christian C. Salvadó
Christian C. Salvadó

Reputation: 827236

The o variable is locally scoped inside the $.fn.ksana function, in order to allow the rotate to reach it, you should either:

  • Simply pass the o variable to it as an argument.
  • Define that function within ksana.
  • Define o in the outer scope.

IMO, passing it as an argument is enough clean:

(function($) {
  $.fn.ksana = function(userOptions) {
    var o = $.extend({}, $.fn.ksana.defaultOptions, userOptions);

    return this.each(function() {
        alert(rotate(o)); // pass o
    });
  };

  function rotate(o) { // use passed object
    return Math.round(o.negRot + (Math.random() * (o.posRot - o.negRot)));
  }
//...
})(jQuery);

Upvotes: 6

Related Questions