保存“this"当从Javascript中的另一个函数调用一个函数时

Preserving "this" when calling a function from another function in Javascript

本文关键字:函数调用 函数 一个 另一个 this quot Javascript 当从 保存      更新时间:2023-09-26

我正在努力解决这个问题。

from Secrets of the Javascript Ninja的示例代码:

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);

这段代码通过向function原型中添加一个函数,为我们提供了一种方便的添加功能的方法。

然而,"this"引用变得混乱,如果我将这个函数转换为使用Javascript中的对象:

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').

问题是"this"被更改为调用者,因此在第二次调用(t.s isPrime.memoized(5))的情况下,"this"被设置为isPrime,这导致memoized正确调用isPrime。但是,当实际调用isPrime时,我希望"this"正确地变成"t"。

有办法做到这一点吗?

可以使用

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

或者修改memoized以通过相应的this。并且不要将其缓存值存储在函数中,这对于共享方法的原型来说是行不通的,但通常每个实例都需要自己的缓存。