DEV Community

loading...

Discussion on: Memoization in JavaScript

Collapse
aminnairi profile image
Amin

Hi Parwinder and thanks for your article.

If you use a constant for your cache, you would still be able to add some keys to it. Plus, it makes reassignment by mistake throw an error which is an added security.

You can even use an immediately invoked function expression to handle to prevent having to call the function to get the closure first.

Plus, your else branch is not necessary since you are returning (and thus stopping the execution of the function) in your conditional statement.

In the end, this proposal could serve as an alternative for implementing the memoized square function.

const square = (() => {
    const cache = {};

    return value => {
        if (typeof cache[value] !== "undefined") {
            console.log("Fetching value from the cache.");
            return cache[value];
        }

        console.log("Computing and storing the result in the cache.");
        return cache[value] = value * value;
    };
})();

console.log(square(2));
console.log(square(4));
console.log(square(6));
console.log(square(6));

// Computing and storing the result in the cache.
// 4
// Computing and storing the result in the cache.
// 16
// Computing and storing the result in the cache.
// 36
// Fetching value from the cache.
// 36
Enter fullscreen mode Exit fullscreen mode

And if you need to create multiple memoized functions, you can even extract the memoization in its own helper function.

const memoize = callback => {
    const cache = {};

    return (...parameters) => {
        const args = JSON.stringify(parameters);

        if (typeof cache[parameters] !== "undefined") {
            console.log("Fetching value from the cache.");
            return cache[parameters];
        }

        console.log("Computing and storing the result in the cache.");
        return cache[parameters] = callback(...parameters);
    };
};

const square = memoize(value => value * value);

console.log(square(2));
console.log(square(4));
console.log(square(6));
console.log(square(6));

// Computing and storing the result in the cache.
// 4
// Computing and storing the result in the cache.
// 16
// Computing and storing the result in the cache.
// 36
// Fetching value from the cache.
// 36
Enter fullscreen mode Exit fullscreen mode
Collapse
shadowtime2000 profile image
shadowtime2000

You could also use a Map for that.

const memoize = (callback) => {
    const cache = new Map();

    return (...parameters) => {
        if (typeof cache.get(parameters) !== "undefined") {
            return cache.get(parameters);
        }
        cache.set(parameters, callback(...parameters));
        return cache.get(parameters);
    }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
radulle profile image
Nikola Radulaški

Why not just cache.get(parameters) !== undefined?

Collapse
bhagatparwinder profile image
Collapse
bhagatparwinder profile image
Parwinder 👨🏻‍💻 Author

Thanks for the feedback @aminnairi . Excellent writeup and valid points. Instead of updating my original post with your recommendation, I am going to add a note to it. Readers can see how I approached it and how you made it better (and the reasoning behind it)

In the case of multiple memorization functions I do however prefer @shadowtime2000 implementation (but that is just a preference based on readability)