插件和"这个"和范围,并与全球一起解决它

时间:2013-03-29 08:19:12

标签: jquery

所以,这不是一个“新”问题,但除了创建一些全局之外,我似乎无法找到解决方案。但是,如果我有多个实例,那么全局将与其他插件实例冲突。例如。

;(function( $, window, document, undefined ) {
    var self = {};
    function Niftyplugin(elem, config){
        this.config = $.extend( {}, $.fn.niftyplugin.config, config );
        this.elem = elem;
        this.$elem = $( elem );
        self.config = this.config;
    }
}

我可以避免继续做这样的事情:

var that = this;

在会产生范围问题的函数中,但如您所见 - 我正在使用全局

var self = {};或我可以使用的任何其他名称。

我的问题是,有更好的方法吗?一种更健壮的方式,我的插件可以在构造函数中分配“this”obj,它不会与其他实例碰撞到某些var / obj?

我试过......

;(function( $, window, document, undefined ) {
    var self = {};
    function Niftyplugin(elem, config, _self){  // <-- passing in _self
        this.config = $.extend( {}, $.fn.niftyplugin.config, config );
        this.elem = elem;
        this.$elem = $( elem );
        _self.config = this.config; // <-- _self
    }
 }


Niftyplugin.prototype = {
   // all the methods, and subsequently in some methods I'd have to use
   // var that = this. In situations of scope. I want to not do this and 
   // make my plugin self-contained with no global vars. But I want to circumvent 
   // need to assign "this" to vars etc..
}

$.fn.niftyplugin = function( config ) {
    if(this.length){
        this.each(function() {
            var nifty = new Niftyplugin( this, config, {} ); // <-- passing in obj
        }
    }
}

我希望我很清楚。

修改 为了更清晰。

让我们说,在我的方法实例中......我有类似的东西:

Niftyplugin.prototype = {
     _create : function(){
         $(someobj).each(function(){
             self.someVar <------ this gives me an error. "self" is undefined.
          })
     }
}

这是我的问题。即使我在构造函数中声明“var self”,它也不会继承到原型方法中。这让我很困惑。现在,如果我将“var self”声明为全局变量然后在构造函数中将其赋值给它,那就很好了。但是,我不想弄乱全球空间(即使它坐在匿名的功能中)。

现在,如果我做了类似

的事情
Niftyplugin.prototype = {
     _create : function(){
         var self = this;
         $(someobj).each(function(){
             self.someVar <------ this works
          })
     }
}

但是我想要避免总是要在每个原型方法中做一个var self = this。因此,我需要一个“this”等效var,我可以在构造函数中声明或传入等...我可以使用。如果我使用插件有各种元素,那var就不会发生冲突。

1 个答案:

答案 0 :(得分:1)

你仍然没有描述你真正试图解决的问题,我怀疑如果我们理解了这一点,我们可以提出更优雅的解决方法,而不是你想在这里强迫解决的问题。

jQuery方法是jQuery对象的一种方法。因此,当调用它时,它将this设置为正在操作的当前jQuery对象。这就是jQuery方法的设计方式以及它们的工作原理。你要么你的方法是一个像这样工作的jQuery方法,要么就是你没有。

如果您只是希望您的jQuery方法可以访问某些全局状态,那么您可以这样做:

(function() {

    // Set up protected global state for my plugin method
    // This data is available only inside this closure.
    // It is global in nature, but is not actually available in the global scope.
    var myData = {};
    myData.whatever = "foo";
    myData.whomever = "joe";

    // define the new jQuery method
    $.fn.niftyplugin = function( config ) {
        // you can access myData state here
        if(this.length){
            this.each(function() {
                // whatever code you need here
            }
        }
    }

})();

这会在闭包中创建一个闭包,只有你的插件方法可以使用这些变量。

除了某个全球状态的定义之外,您还没有描述您可能实际尝试解决的其他问题。请根据实际问题来描述事情,而不是您尝试伪造的javascript解决方案,因为您当前对解决方案的尝试看起来过于复杂或误导,或者至少问题解释得不够好,我们无法知道建议什么


另一方面,如果您想要的是每个实例数据,这个数据对于调用插件方法的每个jQuery对象是独立的,那么,您可以这样做:

(function() {

    // Set up protected global state for my plugin method
    // This data is available only inside this closure.
    // It is global in nature, but is not actually available in the global scope.
    var myData = {};

    // define the new jQuery method
    $.fn.niftyplugin = function( config ) {
       // set instance data on the jQuery object itself
       this.whatever = "foo";
       this.whomever = "joe";
       var self = this;

        if(this.length){
            this.each(function() {
                // inside this callback function, this is a DOM element
                // self is the jQuery obect
                // whatever code you need here
                // you can access self.whatever or self.whomever
                // to get access to instance data on this jQuery object
            }
        }
    }

})();

或者,如果您在插件方法的持续时间内只需要一些数据,则可以使用这样的局部变量:

(function() {

    // Set up protected global state for my plugin method
    // This data is available only inside this closure.
    // It is global in nature, but is not actually available in the global scope.
    var myData = {};

    // define the new jQuery method
    $.fn.niftyplugin = function( config ) {
       // set instance data on the jQuery object itself
       var whatever = "foo";
       var whomever = "joe";

        if(this.length){
            this.each(function() {
                // inside this callback function, this is a DOM element
                // whatever code you need here
                // you can access whatever or whomever
                // to get access to local variables during this method call
            }
        }
    }

})();

由于您在问题中添加了更多内容,因此这里有更多信息。如果你有这种类型的结构:

Niftyplugin.prototype = {
     _create : function(){
         var self = this;
         $(someobj).each(function(){
             self.someVar <------ this works
          })
     }
}

您希望访问each()回调中的对象实例,那么您最好的办法是将this保存到单独的本地变量self中。 。 this被重新分配给.each()回调中的其他内容,因此如果您想要访问原始this,则必须将其保存在其他位置。如果你想在没有全局变量的情况下干净利落(这是推荐),那么你必须在回调函数范围内的局部变量中进​​行。在此处提供的代码段中,您干净利落的唯一选择是为每种方法添加var self = this


可以使用共享公共self的不同构造。

function Niftyplugin() {
    var self = this;

    this._create = function() {
        $(someobj).each(function(){
            self.someVar <------ this works
        })
    }

    this._update = function() {
        this.each(function(){
            self.someVar <------ this works
        })
    }
}