记住原型方法

时间:2013-05-30 23:41:01

标签: javascript memoization

我正在尝试使用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);
};

我可以让它运行,我只是无法记住它。我知道有些事情是错的,但我无法弄清楚是什么。我知道有很多关于如何记忆的例子,但我没有遇到过这样的范围。

2 个答案:

答案 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字符串和状态/版本属性,多个参数可以连接成一个字符串...)

完全另一种解决方案是在构造函数中创建方法,而不是在原型中创建它。但这与在实例属性中使用方法缓存一样严重污染。更糟糕的是,我想。