16

クラスに次の機能があります。

MyClass.prototype.myFunction = function(item, args) 
{       
    console.log(this);
}

この関数は、変更するアクセス権がない外部ライブラリから呼び出されます。呼び出されると、コンソールは、実際のインスタンス化されたオブジェクトではなく、ウィンドウ オブジェクトとして「this」をログに記録します。stackoverflow を検索すると、次の引用が見つかりました。

これは、メソッドの記述方法ではなく、メソッドの呼び出し方法に従って設定されます。したがって、obj.method() の場合、これは method() 内の obj に設定されます。obj.method.call(x) の場合、method() 内の this は x に設定されます。呼び方で決まります。これが意味することは、例えば onclick へのコールバックとして渡すと、これは期待したものではなく、グローバル ウィンドウ オブジェクトに設定されるということです。

これが起こっていることであり、その呼び方を変えることはできないと思います。私の質問は、それが呼び出された方法に関係なく、オブジェクトのインスタンスを取得する方法はありますか?

4

4 に答える 4

4

おそらく、関数参照が他の関数に渡されて呼び出され、その関数が次のようなものであるとします。

function otherFunction(args, fn) {
    ...
    fn();
    ...
}

メソッドがthis必要なものを取得できるようにするには、次のようにします。

// Create a local variable referencing the `this` you want
var instance = this;

// Pass a function that has a closure to the variable
// and sets the appropriate this in the call
otherFunction(args, function(){myMethod.call(instance)})

thismyMethodはどんなinstance参照でもあります。instanceの呼び出し後otherFunction、メソッドが呼び出される前にの値を変更すると、myMethodはその新しい値を取得することに注意してください。

それが問題であれば、あなたもそれに対処することができます。

ああ、インスタンスへのクロージャーを持つ独自のメソッドを各インスタンスに与えることにより、コンストラクターでこれを処理することもできます。

function MyObj(name) {
  var instance = this;
  instance.name = name;
  instance.getName = function() {
    return instance.name;
  }
}

var anObj = new MyObj('fred');

// Call as a method of anObj
alert(anObj.getName());  // fred 

// Pass method as a reference
var x = anObj.getName;

// Unqualified call
alert(x());  // fred    
于 2012-11-05T01:09:57.883 に答える
1

myFunction()修正の 1 つは、インスタンスごとにのコピーを作成することです。つまり、プロトタイプではなく、コンストラクターで作成します。これにより、コンストラクターにthisローカル変数として格納されたへの参照を保持できるためです。

function MyClass() {
    var self = this;
    this.myFunction = function(item, args) {
        // use self instead of this
        console.log(self);
    };
    // other constructor code here
}

ただし、もちろん、すべてのインスタンスに対して関数を作成すると、より多くのメモリが使用されます。これは、関数のサイズによっては問題になる場合とそうでない場合があります。妥協案は、関数のラッパーをコンストラクター内に配置し、プロトタイプで実際の関数を定義することです。

function MyClass() {
    var self = this;
    this.myFunction = function(item, args) {
        return self.wrappedMyFunction(item, args);
    };

    // your other constructor code here
}    
MyClass.prototype.wrappedMyFunction = function(item, args) 
{       
    console.log(this);
}
于 2012-11-05T01:23:24.863 に答える