10

JavaScriptをオブジェクト指向で使用するときにvarself= thisを宣言する方法を知っている人はいますか?私はそれをかなり頻繁に見ます、そしてそれがあなたがしなければならないことだけなのか、それともあなたがそれを回避する方法(おそらくクラスライブラリ?)が本当にあるのか興味がありましたか?なぜそれが必要なのかはわかります(これには関数スコープがあります)。しかし、あなたはそこにどんな賢い方法があるかもしれないかを決して知りません。

たとえば、私は通常、JSで次のように「クラス」をコーディングします。

function MyClass() {

}

MyClass.prototype = {

    firstFunction: function() {

        var self = this;

        $.ajax({
            ...
            success: function() {
                self.someFunctionCall();

            }
        });
    },

    secondFunction: function() {

        var self = this;

        window.setTimeout(function() {
            self.someOtherFunction();
        }, 1000);
    }

};
4

6 に答える 6

6

あなたの最初の関数でこれを行うことができます...

$.ajax({
    context: this,
    success: function() {
        this.someFunctionCall();

    }
});

2つ目では、これを行うことができますが.bind()、古いブラウザではシムする必要があります...

window.setTimeout(function() {
    this.someOtherFunction();
}.bind(this), 1000);

jQueryを使用すると、これを行うこともできます...

window.setTimeout($.proxy(function() {
    this.someOtherFunction();
}, this), 1000);
于 2012-07-25T01:40:51.583 に答える
1

thisいいえ、別のコンテキスト(コールバックなど)で参照する場合は、これを行う必要があります。そうしないと、などの別のオブジェクトに再割り当てされwindowます。

ちなみに、これselfはPythonの規則です。JavaScriptでは、一般的に規則を使用しますthat = this。しかし、それは個人的な好みの問題です。

于 2012-07-25T01:37:55.640 に答える
1

ES5は、関数のと最初のn個のパラメーターbindをバインドできるという標準メソッドを追加しました。上記の例では、を呼び出すthisことで使用を回避できます。selfbind

$.ajax({ 
    ... 
    success: function() { 
        this.someFunctionCall(); 
    }.bind(this); 
}); 

ES5以外のブラウザーの場合は、https ://github.com/kriskowal/es5-shimにあるようなシムを使用できます。

余談ですが、はグローバルスコープと等しいグローバル変数として定義されているselfため、コーディングパターンでの使用は避けます。つまり、誤って定義するのを忘れた場合、例外ではなく値としてグローバルスコープをサイレントに取得します。代わりに使用すると、例外が発生します(上記の誰かが定義した場合を除く)。selfwindowselfthat

于 2012-07-25T02:03:52.110 に答える
0

一部のJavaScriptフレームワークには、ハンドラー関数のコンテキストを設定できる独自のイベント処理メカニズムがあります。このように、を使用する代わりに、単にコンテキストとしてself = this指定できます。this

私の頭に浮かぶ他の可能性は、グローバルスコープのどこかにコンテキストを渡すことです。好き

function MyClass() {
    MyClass.instances.push(this);
}

MyClass.instances = new Array();
MyClass.getInstanceBySomeRelevantParameter = function(param) {
     for (var i = 0; i < MyClass.instances.length; i++)
         if (condition(param))
             return MyClass.instances[i];
}

...

success: function(event) {
    MyClass.getInstanceBySomeRelevantParameter(event).someFunctionCall();
}
于 2012-07-25T01:43:26.283 に答える
0

いつでもメソッドをにバインドしthisて、次のように使用できます。

function MyClass() {

}

MyClass.prototype = {

    firstFunction: function() {

        var funct = someFunctionCall.bind(this);

        $.ajax({
            ...
            success: function() {
                funct();

            }
        });
    },

    secondFunction: function() {

        var funct = someOtherFunction.bind(this);

        window.setTimeout(function() {
            funct();
        }, 1000);
    }

};

プロパティの場合は、それらを別の変数に割り当てるだけです。

于 2012-07-25T01:44:52.820 に答える
0

私はJSFiddleに騙されて、以下を思いついた。トップレベルの名前空間を使用していることを前提としています。これにより、自分自身を1回だけ宣言する必要があります(下部)。クラスを無名関数でラップしたので、selfはグローバルスコープを持ちません。フィドルは次のとおりです。http://jsfiddle.net/bdicasa/yu4vs/

var App = {};
(function() {
    App.MyClass = function() { }

    App.MyClass.prototype = {

        firstFunction: function() {

            console.log('in first function');
            console.log(self === this); // true
        },

        secondFunction: function() {


            window.setTimeout(function() {
                self.firstFunction();
                console.log(self === this); // false
            }, 100);
        }

    };
    var self = App.MyClass.prototype;
})();

var myClass = new App.MyClass();
myClass.secondFunction();
于 2012-07-25T02:16:35.590 に答える