我正在尝试使用memoization来加速我的Javascript,但我需要proto
方法,我需要所述方法来访问this
对象,它给了我适合。这就是我所拥有的:
MyObj.prototype.myMethod = function(){
var self = this
, doGetData = (function() {
var memo = []
, data = function(obj) {
var result = memo;
if (obj.isDirty) {
obj.isDirty = false;
result = $.map(obj.details, function(elem, i) {
return elem.export();
});
memo = result;
}
return result;
}
return data;
}())
;
return doGetData(self);
};
我可以让它运行,我只是无法记住它。我知道有些事情是错的,但我无法弄清楚是什么。我知道有很多关于如何记忆的例子,但我没有遇到过这样的范围。
答案 0 :(得分:1)
如果你想在原型上使用该函数,但是你希望它独立地为每个实例进行memoize,那么“memo”需要是一个实例属性(或者闭包可以是实例属性,我猜;无论哪个)。 / p>
MyObj.prototype.myMethod = function() {
if (!("memo" in this) || this.isDirty) {
this.isDirty =false;
this.memo = $.map(obj.details, function(elem, i) {
return elem.export();
});
}
return this.memo;
};
我不认为你可以在不污染实例的情况下做到这一点,尽管你可以使用更新的JavaScript功能来保持“备忘录”的东西不被枚举。毕竟,原型由所有实例共享。
答案 1 :(得分:0)
可以使用Map对象存储和检索所有实例的方法缓存。地图支持对象作为键。 (一种偏离主题,但是严格的模式会影响"这个"的传播。现在没有" var self = this;&#34 ;.)
"use strict";
MyObj.prototype.myMethod = function() {
var prototypeCache = new Map();
return function(arg) {
if (!prototypeCache.has(this)) prototypeCache.set(this, new Map());
var instanceCache = prototypeCache.get(this);
if (instanceCache.has(arg)) return instanceCache.get(arg);
else {
//Do expensive calculation that is stored in result...
instanceCache.set(arg, result);
return result;
}
};
}();
现在为了简单起见,我还为instanceCache使用了Map。对于速度,通常只使用一个对象。这取决于人们可以制作的钥匙。通常可以找到通过唯一字符串存储的方法。 (数字可以转换,对象可以有id字符串和状态/版本属性,多个参数可以连接成一个字符串...)
完全另一种解决方案是在构造函数中创建方法,而不是在原型中创建它。但这与在实例属性中使用方法缓存一样严重污染。更糟糕的是,我想。