我正在努力解决这个问题。
来自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”。
无论如何要实现这个目标吗?
答案 0 :(得分:2)
您可以使用
t.isPrime = t.isPrime.bind(t);
t.isPrime.memoized(5);
或修复memoized
以传递相应的this
。而不是将其缓存值存储在函数上,这对于共享方法但通常每个实例都需要自己的缓存的原型不起作用。