2016-10-28 8 views
1

この問題を解決しようとしています。 Javascriptの忍者の秘密からJavascriptで別の関数から関数を呼び出すときに "this"を保持する

サンプルコード:

Function.prototype.memoized = function(key){ 
    this._values = this._values || {}; 
    return this._values[key] !== undefined ? 
     this._values[key] : 
    this._values[key] = this.apply(this, arguments); 
}; 
function isPrime(num) { 
    var prime = num != 1; 

    for (var i = 2; i < num; i++) { 
    if (num % i == 0) { 
     prime = false; 
     break; 
    } 
    } 
    return prime; 
} 
alert(isPrime.memoized(5); 

このコードは、私たちに関数のプロトタイプに関数を追加することで、機能を追加する便利な方法を提供します。

私はJavaScriptでオブジェクトを使用するには、この機能を変換する場合は、 "this" 参照が、めちゃくちゃます:

JSFiddleリンク:https://jsfiddle.net/vcqqc8a8/3/

function Test() { 
    this.testVar = 2; 
}; 

Test.prototype.isPrime = function (num) { 
    alert(this.testVar); // This works, when isPrime is called through obj.isPrime(), but not when its called through memoized() 
    var prime = num != 1; 

    for (var i = 2; i < num; i++) { 
    if (num % i == 0) { 
     prime = false; 
     break; 
    } 
    } 
    return prime; 
}; 

var t = new Test(); 
t.isPrime(5);       // "this" inside Test.prototype.isPrime is correctly set to "t" 
t.isPrime.memoized(5);  // "this" inside Test.prototype is set to isPrime (expected behavior, but I want it to be preserved to "t'). 

問題は、 "これは" であるということです2番目の呼び出し(t.isPrime.memoized(5))の場合、 "this"はisPrimeに設定され、memoizedはisPrimeを正しく呼び出すようになります。しかし、実際にisPrimeが呼び出されたとき、「this」が正しく「t」になるようにします。

これを達成するにはどうすればよいですか?

+0

この使用法をサポートする唯一の方法は、すべての 'Test'オブジェクトにコンストラクタ内の独自の' isPrime'関数を与えることです。 – melpomene

+0

*ただし、実際にisPrimeが呼び出されたとき、「this」は正しく「t」になります。*間違っています。 'this'はあなたの' isPrime'メソッドの中の 't'を参照します –

+0

@ TheReason何と言っていますか? 'isPrime'の呼び出し時に' this'は 'isPrime'です。 – melpomene

答えて

2

あなたは

t.isPrime = t.isPrime.bind(t); 
t.isPrime.memoized(5); 

を使用するか、適切なthisを渡すためにmemoizedを修正します。関数にキャッシュ値を格納しないでください。実際にはメソッドが共有されているプロトタイプでは機能しませんが、通常は各インスタンスに独自のキャッシュが必要です。

関連する問題