0

したがって、これは「新しい」問題ではありませんが、グローバルを作成する以外に解決策が見つからないようです。しかし、複数のインスタンスがある場合、そのグローバルは他のプラグイン インスタンスと衝突します。例えば。

;(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が必要です。そして、プラグインを使用するさまざまな要素がある場合、その変数は衝突しません。

4

1 に答える 1

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ような別のローカル変数に保存することですselfthisはコールバックで別のものに再割り当てされる.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
        })
    }
}
于 2013-03-29T08:41:03.977 に答える