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

Create a simple JS object that modifies itself

本文关键字:简单 对象 JS 修改 一个 创建      更新时间:2023-09-26

所以我对面向对象的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()。后者是我想要的。

非常感谢。

函数是对象,而且通常是方便的对象:

function foo(arg) {
  if (!foo["cache"+arg]) foo["cache"+arg] = doSomething(arg);
  return foo["cache"+arg];
}

当然,这只适用于唯一的字符串和数字参数;它混淆了"1"answers"1"。它也不会缓存false、0、"等返回值。如果这对你很重要,可以考虑在需要强类型查找功能的应用程序中使用WeakMaps。

封装缓存类的facade如何?

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将是私有作用域的返回值,一个函数,它接受一个参数,并使用缓存类来生成值

我不知道这是否真的是你想要的但是静态变量似乎解决了你的问题:

<>之前函数foo (arg){If (typeof foo。Mycache == 'undefined')foo。Mycache = {};If (typeof foo。Mycache [arg] == 'undefined')foo。mycache[arg] = doSomething(arg);返回(foo.mycache (arg));}函数doSomething (arg){返回参数+"! !";}

我以前写过一个函数,它将一个"常规"函数转换为您描述的函数。像这样使用: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);
  };
}