在Javascript中从另一个函数调用函数时保留“this”

时间:2016-10-28 07:55:01

标签: javascript this

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

来自Javascript Ninja的Secrets的示例代码:

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原型添加函数,为我们提供了添加功能的便捷方式。

然而,如果我将此函数转换为在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').

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

无论如何要实现这个目标吗?

1 个答案:

答案 0 :(得分:2)

您可以使用

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

或修复memoized以传递相应的this。而不是将其缓存值存储在函数上,这对于共享方法但通常每个实例都需要自己的缓存的原型不起作用。