使用eval记住实施.使用eval是否可以接受? [英] Memoize implementation using eval. Is this use of eval acceptable?

查看:86
本文介绍了使用eval记住实施.使用eval是否可以接受?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

...还是有更好的方法来实现备忘?

...or are there better ways to implement a Memoization?

Function.memoize = function(callableAsString)
    {
    var r = false, callable, code;
    try
        {
        callable = eval(callableAsString);
        if (typeof callable == "function" && typeof(Function.memoize.cache[callableAsString]) == "undefined")
            {
            code = callableAsString + " = function()" + 
                "{" +
                "var cache = Function.memoize.cache['" + callableAsString + "'];" +
                "var k = Json.stringify([this].concat(arguments));" +
                "return cache.r[k] || (cache.r[k] = cache.c.apply(this, arguments));" +
                "};" +
                "true;";
            if (r = eval(code))
                {
                Function.memoize.cache[callableAsString] = {c: callable, r: {}};
                }
            }
        }
    catch (e) {}
    return r;
    };
Function.memoize.cache = {};
Function.memoize("String.prototype.camelize");

根据Felix Kling的建议进行更新

Function.memoize = function(callable)
    {
    var r = false;
    if (typeof callable == "function")
        {
        var hash = callable.toString().hashCode();
        r = function()
            {
            var cache = Function.memoize.cache[hash];
            var key = Json.stringify([this].concat(arguments));
            return cache.r[key] || (cache.r[key] = cache.c.apply(this, arguments));
            }
        if (!Function.memoize.cache)
            {
            Function.memoize.cache = {};
            }
        r.memoize = callable;
        Function.memoize.cache[hash] = {c: callable, r: {}};
        }
    return r;
    };

Function.unmemoize = function(callable)
    {
    if (callable.memoize && typeof callable.memoize == "function")
        {
        return callable.memoize;
        }
    else
        {
        return false;
        }
    };

String.prototype.camelize = Function.memoize(String.prototype.camelize);
String.prototype.camelize = Function.unmemoize(String.prototype.camelize);

推荐答案

我不认为需要评估...考虑此实现

I don't see the need for eval... consider this implementation

function memoize(f, cache)
{
    if (!cache) cache = {};
    return function()
    {
        var key = JSON.stringify(arguments);
        return (cache[key] || (cache[key] = [f.apply(this, arguments)]))[0];
    }
}

请注意,我故意忽略了键中的this.原因是this可能无法由stringify进行序列化(例如,由于循环),并且这是规则,而不是例如this == window时(即在全局上下文中)的例外情况.

Note that I deliberately ignored this in the key. The reason is that this may not be serializable by stringify (e.g. because of loops) and this is more the rule than the exception for example when this == window i.e. in the global context.

IMO有用的是显式传递缓存的功能,这样您就可以通过执行以下操作来为每个实例创建一个单独的缓存,或者为所有实例创建一个共享的缓存:

What is IMO useful is the ability to explictly pass the cache, so that you can for example create a separate cache for each instance or one shared cache for all instances by doing something like:

function MyObj(...)
{
    // every instance has its own cache
    this.foo = memoize(function(...) { ... });

    // there is one shared cache for all instances
    this.bar = memoize(function(...) { ... }, MyObj.memoize_cache);
}

MyObj.memoize_cache = {};

这篇关于使用eval记住实施.使用eval是否可以接受?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆