因此,我开始使用面向对象的JavaScript。我想要的是创建一个简单的全局对象(如jQuery,_,d3等),您可以将其作为具有单个参数的函数调用。然后检查它是否已经知道该参数,如果知道该参数,则返回缓存的信息。否则它会获取新信息并在返回之前对其进行缓存。所以,相当于:
var cache = {};
function foo(arg) {
if (!cache[arg]) cache[arg] = doSomething(arg);
return cache[arg];
}
function doSomething(arg) {
return arg+"!!!";
}
foo("hi"); //returns "hi!!!" after calling doSomething
foo("hi"); //returns "hi!!!" from cache without calling doSomething
我无法弄清楚如何将缓存汇总到foo本身,以便在调用时检查/更新自己的哈希,而不是仅使用单独的全局变量。我知道如果我做了这样的话会有用:
function cacher() {
this.cache = {};
}
cacher.prototype = {
update: function(arg) {
if (!this.cache[arg]) this.cache[arg] = doSomething(this.cache[arg]);
return this.cache[arg];
}
}
但在这种情况下,我必须拨打foo.update()
而不是foo()
。后者就是我想要的。
任何帮助都非常感激。
答案 0 :(得分:0)
函数是对象,通常是方便的:
function foo(arg) {
if (!foo["cache"+arg]) foo["cache"+arg] = doSomething(arg);
return foo["cache"+arg];
}
当然,这只适用于唯一的字符串和数字参数;它让人感到困惑" 1" 1。 它也不会缓存false,0,""等的返回。 如果这对您很重要,请考虑对需要强类型查找功能的应用程序使用WeakMaps。
答案 1 :(得分:0)
封装缓存类的外观怎么样?
var foo = (function() {
function cacher() {
this.cache = {};
}
cacher.prototype.update = function(arg) {
if (!this.cache[arg]) this.cache[arg] = this.doSomething(this.cache[arg]);
return this.cache[arg];
}
cacher.prototype.doSomething = function(arg) {
//Do something with arg and return
}
var func = new cacher();
return function(arg) {
return func.update(arg);
}
}());
var val = foo("checking");
您可以使用简单的接口使您的缓存类变得复杂,在这种情况下foo
将是私有范围的返回值,一个函数,它接受一个参数并使用缓存类生成价值观。
答案 2 :(得分:0)
我不知道它是否真的是你想要的,但静态变量似乎解决了你的问题:
function foo(arg) { if (typeof foo.mycache == 'undefined') foo.mycache = {}; if (typeof foo.mycache[arg] == 'undefined') foo.mycache[arg] = doSomething(arg); return (foo.mycache[arg]); } function doSomething(arg) { return arg+"!!!"; }
答案 3 :(得分:-1)
我前段时间写过一个函数,它将“常规”函数转换为一个按照你描述的方式运行的函数。像这样使用它:var cachedFunction = memoize(regularFunction)
。缓存保存在闭包内。应该使用任意数量的参数。
function memoize(oriFunc) {
var cache = [];
var notFound = {};
function arrayEqual(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
var ri = arr1.length;
while (ri--) {
if (arr1[ri] !== arr2[ri]) {
return false;
}
}
return true;
}
function cacheGet(newArgs) {
var ri = cache.length;
while (ri--) {
var item = cache[ri];
if (arrayEqual(item.args, newArgs)) {
return item.result;
}
}
// I'm returning a special object, since false, -1, or undefined could be
// results of the call
return notFound;
}
function cachePut(args, result) {
cache.push({args: args, result: result});
return result;
}
return function() {
var cacheResult = cacheGet(arguments);
if (cacheResult !== notFound) {
return cacheResult;
}
var freshResult = oriFunc.apply(this, arguments);
return cachePut(arguments, freshResult);
};
}