如果有人可以简单地一步一步解释这里发生的事情,那将非常有帮助。我知道memoize()正在缓存函数,但我需要更好的理解。谢谢!

var memoize = function (f) {
  var cache = {};
  return function () {
    var str = JSON.stringify(arguments);
    cache[str] = cache[str] || f.apply(f, arguments);
    return cache[str];
  };
};

var mUser = memoize(function(x){
  return function() {
    return x;
  };
});

var x = mUser(1);
var y = mUser(2);
console.log(x());  //1
console.log(y());  //2

编辑:我保留原始记录。但是发布修改后的代码以及我对此的理解。如果我是对还是错,我需要提出意见,并要求其中的一些解释。
var memoize = function (injected) {
  var cache = {};
  return function closure_with_access_to_cache () {
    var str = JSON.stringify(arguments);
    cache[str] = cache[str] || injected.apply(injected, arguments);
    console.log(cache);
    return cache[str];
  };
};

var memoizeUser = memoize (function injected(a) {
  return function closure_with_access_to_a () {
    return a;
  };
});

memoizeUser();

让我们尝试回溯事物。

首先,当执行memoizeUser();语句时,memoizeUser代表什么?或者首先调用哪个函数?
var memoizeUser = ...是一个函数表达式,表示它没有被吊起。

因此,memoize被调用。

但是,var memoize = ...也是一个函数表达式。仔细看,它是一个closure_with_access_to_cache闭包,并在调用时接收传递给memoizeUser的参数。

在此closure_with_access_to_cache内部,第一次cache为空,因此injected.apply(injected, arguments)被执行并获得另一个闭包closure_with_access_to_a作为返回值。此值存储到cache,然后返回。因此,memoizeUser实际上变成closure_with_access_to_a,且a等于传递给memoizeUser的值。

让我们看一些 call 和日志。
console.log(memoizeUser());
{ '{}': [Function: closure_with_access_to_a] }
[Function: closure_with_access_to_a]

缓存键是空对象,因为没有将任何参数作为参数传递给memoizeUser()memoizeUser()返回已记录的函数closure_with_access_to_a
console.log(memoizeUser()());
{ '{}': [Function: closure_with_access_to_a] }
undefined
memoizeUser()返回函数closure_with_access_to_a,该函数将被调用并记录为undefined,这是a的值,因为未将任何内容传递给memoizeUser
memoizeUser(1);
{ '{"0":1}': [Function: closure_with_access_to_a] }

与上述类似,但a的值为1。
console.log(memoizeUser(1)());
{ '{"0":1}': [Function: closure_with_access_to_a] }
1

与上述类似,但a的值为1。

最佳答案

因此,从本质上讲,这是确保对传递给它的任何给定参数集的任何给定函数仅执行一次。

当为给定功能执行备忘录功能时,该备注功能将返回一个在上下文中具有该缓存的新功能。它要做的第一件事是创建arguments对象的JSON字符串表示形式,以用作该特定结果的唯一键。

然后,它使用null合并运算符将缓存值设置为自身(如果已存在)或设置为应用了这些参数的注入(inject)函数的结果。

如果您实际命名正在使用的所有功能,则这更有意义:

function memoize(injectedFunction) {
  var cache = {};
  return function memoizedFunction() {
    // 'arguments' here is the arguments object for memoizedFunction.
    var cacheKey= JSON.stringify(arguments);

    // This is a logical OR which is null coalescing in JS. If cache[str]
    // is null or undefined, the statement proceeds to call injectedFunction.apply.
    // If it's not, then it returns whatever is stored there.
    cache[cacheKey] = cache[cacheKey] || injectedFunction.apply(injectedFunction, arguments);
    return cache[cacheKey];
  };
};

因此,本质上,考虑一个简单的加法函数:
function add(a, b) { return a + b; }

var memoizedAdd = memoize(add);

console.log(memoizedAdd(1, 2));

此时,memoizedAdd使用参数1、2运行。这将创建"{\"0\": 1, \"1\": 2}"的cacheKey,然后设置cache[cacheKey] = add.apply(add, [1 ,2])(实际上,在其中,它实际上将“add”视为“injectedFunction”。

下次运行memoizeAdd(1,2)时,如果没有再次运行add()函数,则会从缓存中获得3的相同结果。

希望一切都有意义。

09-17 06:01