Javascript 如何在jQuery中正确地定义变量的范围?

Javascript 如何在jQuery中正确地定义变量的范围?,javascript,jquery,scope,Javascript,Jquery,Scope,我正在开发一个jQuery插件,但在正确确定变量的范围时遇到了一些问题。下面是我的代码中的一个示例: (function($) { $.fn.ksana = function(userOptions) { var o = $.extend({}, $.fn.ksana.defaultOptions, userOptions); return this.each(function() { alert(rotate()); // o is not defined

我正在开发一个jQuery插件,但在正确确定变量的范围时遇到了一些问题。下面是我的代码中的一个示例:

(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);

我试图让私有函数rotate能够看到o变量,但它只是不断发出“o未定义”的警报。我不确定我做错了什么。

变量
o
$.fn.ksana
函数中是局部作用域,为了允许
旋转
到达它,您应该:

  • 只需将
    o
    变量作为参数传递给它即可
  • 在ksana中定义该函数
  • 在外部范围中定义
    o
在国际海事组织,将其作为一个论据传递已经足够清晰:

(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);

o
变量在
$.fn.ksana
函数中是局部作用域,为了允许
旋转
到达它,您应该:

  • 只需将
    o
    变量作为参数传递给它即可
  • 在ksana中定义该函数
  • 在外部范围中定义
    o
在国际海事组织,将其作为一个论据传递已经足够清晰:

(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);

您必须将
o
放在
rotate
ksana
的作用域中,即放在根
函数($)
作用域中。像这样:

(function($) {

var o;

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

但是你为什么不把它变成旋转的参数呢?为什么需要使其成为一种“全局的”

您必须将
o
放在
rotate
ksana
的范围内,即放在根
函数($)
范围内。像这样:

(function($) {

var o;

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

但是你为什么不把它变成旋转的参数呢?为什么需要将其设置为“全局”?

您可以将旋转函数设置为与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()); 
    });
};
或者,只需将其传递以旋转:

(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)));
};

您可以将旋转函数置于与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()); 
    });
};
或者,只需将其传递以旋转:

(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)));
};

+1由于您没有在插件外部公开
rotate
,因此最好将变量作为参数传入,以避免出现不必要的全局状态。这可能是一个愚蠢的问题,但这是否会产生额外的开销?我将有很多函数需要访问o,所以我会传递很多o…@safetycopy:嗯,你可以将
o
暴露给更多函数,就像我在第三种方法中所说的,在封闭的范围内定义
o
。因此,这看起来像:
(function($){var o=null;$.fn.ksana=function(userOptions){o=$extend({},$.fn.ksana.defaultOptions,userOptions);
对吗?@safetycopy:对,顺便说一句,您实际上不需要分配
null
(除非您特别想要),如果您不分配任何内容,即
var o;
o将包含
undefined
,您也可以在函数声明之后(如原始帖子中的
rotate
).+1既然你没有将
rotate
暴露在插件之外,那么不妨将变量作为参数传递进来,以避免出现不必要的全局状态。这可能是一个愚蠢的问题,但这不会产生额外的开销吗?我将有很多函数需要访问o,所以我会传递很多o…@safetycopy:Well、 您可以向更多函数公开
o
,就像我在第三种方法中所说的,在封闭范围中定义
o
;正确吗?@safetycopy:对了,顺便说一句,如果你不指定任何内容,比如
var o;
o将包含
未定义的
,你也可以在函数声明之后(比如
在原始帖子中旋转
).o从用户和默认选项合并。如果它在根函数的作用域中,我认为我无法实现。o从用户和默认选项合并。如果它在根函数的作用域中,我认为我无法实现。是否将旋转函数移动到与o相同的作用域以保持旋转私有?是否移动rotate函数的作用域与o保持私有旋转相同?