创建一个修改自身的简单JS对象

时间:2014-03-13 22:44:42

标签: javascript oop

因此,我开始使用面向对象的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()。后者就是我想要的。

任何帮助都非常感激。

4 个答案:

答案 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);
  };
}