Can anyone please explain what is going on in the below code using JS technology and memoization

It would be very helpful if someone could explain what is happening here step by step in a simple way. I know it memoize()

caches functions, but I need a better understanding. Thank!

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

      

Edit: I keep the original for writing. But posting the modified code and my understanding of it. I need opinions if I am right or wrong and some explanation.

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();

      

Try to back off.

First of all, when the statement is executed memoizeUser();

, what is presented memoizeUser

or which function is called first?

var memoizeUser = ...

- function expression, means that it does not rise.

So, it is called memoize

.

But, var memoize = ...

it is also a function expression. Looking at it carefully, it's a closure closure_with_access_to_cache

and getting the parameter passed memoizeUser

when it's called.

Inside this closure_with_access_to_cache

, the first time is cache

empty, so injected.apply(injected, arguments)

it gets executed and gets another closure closure_with_access_to_a

as its return value. This value is stored in cache

and then returned. So it memoizeUser

actually becomes closure_with_access_to_a

with a

equal value passed to memoizeUser

.

Take a look at some challenges and logs.

console.log(memoizeUser());
{ '{}': [Function: closure_with_access_to_a] }
[Function: closure_with_access_to_a]

      

The cache key is an empty object because nothing was passed as a parameter to memoizeUser()

. memoizeUser()

returns a function closure_with_access_to_a

that is being registered.

console.log(memoizeUser()());
{ '{}': [Function: closure_with_access_to_a] }
undefined

      

memoizeUser()

returns a function closure_with_access_to_a

that gets called and registers undefined, which was the value a

since nothing was passed memoizeUser

.

memoizeUser(1);
{ '{"0":1}': [Function: closure_with_access_to_a] }

      

As above, except for the a

value 1.

console.log(memoizeUser(1)());
{ '{"0":1}': [Function: closure_with_access_to_a] }
1

      

As above, except for the a

value 1.

+3


source to share


2 answers


So, in essence, this means that any given function will only be executed once for any given set of arguments that you pass to it.

The memoize function, when executed for a given function, returns a new function that has this cache in context. The first thing it does is create a JSON string representation of the arguments object to use as a unique key for that particular result.

It then uses the null coalescing operator either to set the cache value for itself (if it already exists) or for the results of the injected function using those arguments.

This makes sense if you are actually calling all the functions you are playing with:

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 not, then it returns whatever is stored there.
    cache[cacheKey] = cache[cacheKey] || injectedFunction.apply(injectedFunction, arguments);  
    return cache[cacheKey];
  };
};

      



So basically, let's look at a simple function to add:

function add(a, b) { return a + b; }

var memoizedAdd = memoize(add);

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

      

At this point memoizedAdd is started with arguments 1, 2. This creates a cacheKey "{\"0\": 1, \"1\": 2}"

and then sets cache[cacheKey] = add.apply(add, [1 ,2])

(actually, of course, internally there it thinks of 'add' as 'injectedFunction'.

The next time you run memoizeAdd (1,2), you will get the same result out of 3 from the cache without running the add () function again.

Hope that all makes sense.

+1


source


What does it mean to memoize()

cache functions? This means that the functions are not executed, but a cached result is returned instead. The result of a (pure) function is always based on its arguments. If you call the function with the same arguments, it will return the same result. Therefore, we can store the results in an object cache

with arguments (or a str

string representation of it) as a key and the function's result as a value:

cache[str] = f.apply(f, arguments);

      

apply

is used to apply function f to the array of arguments we provide, in which case all the arguments of our f

function are called.

cache[str] = cache[str] || f.apply(f, arguments);

      

is a shorthand way to set the default for cache[str]

. If cache[str]

not set, then the function will be called f

and the result saved.



Also interesting is the function that you remember in your example. It takes one argument and returns a function. x

and y

are functions. You can invoke them by adding a ()

list of empty arguments. This is why the last lines are read

console.log(x());  //1
console.log(y());  //2

      

In JavaScript, if you use the function keyword in another function, you create a closure.

Due to closure, a local variable (local variable x

) may remain accessible after returning from the called function.

When mUser is called with 1 as an argument, the local variable x is 1. The return function captures this state inside what is called a closure. Closure is a way of storing the values โ€‹โ€‹of local variables along with a function.

+1


source







All Articles