【发布时间】:2011-09-21 09:57:54
【问题描述】:
...或者有更好的方法来实现记忆?
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);
【问题讨论】:
-
我看不出比仅传递函数引用有任何优势。另请注意,如果您有具有循环引用的对象,
JSON.stringify将失败。 -
感谢您的意见。仅供参考:我正在使用 JSON.stringify 的包装器,它使用 replacer 参数来处理循环引用和 DOM 对象的“序列化”。这是必需的,因为参数数组也可以包含具有循环引用的对象。
标签: javascript eval memoization