> [Memoize](https://en.wikipedia.org/wiki/Memoization) functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input
Memory is automatically released when an item expires or the cache is cleared.
<!-- Please keep this section in sync with https://github.com/sindresorhus/p-memoize/blob/main/readme.md -->
By default, **only the memoized function's first argument is considered** via strict equality comparison. If you need to cache multiple arguments or cache `object`s *by value*, have a look at alternative [caching strategies](#caching-strategy) below.
If you want to memoize Promise-returning functions (like `async` functions), you might be better served by [p-memoize](https://github.com/sindresorhus/p-memoize).
By default, only the first argument is compared via exact equality (`===`) to determine whether a call is identical.
```js
constpower=mem((a,b)=>Math.power(a,b));
power(2,2);// => 4, stored in cache with the key 2 (number)
power(2,3);// => 4, retrieved from cache at key 2 (number), it's wrong
```
You will have to use the `cache` and `cacheKey` options appropriate to your function. In this specific case, the following could work:
```js
constpower=mem((a,b)=>Math.power(a,b),{
cacheKey:arguments_=>arguments_.join(',')
});
power(2,2);// => 4, stored in cache with the key '2,2' (both arguments as one string)
power(2,3);// => 8, stored in cache with the key '2,3'
```
More advanced examples follow.
#### Example: Options-like argument
If your function accepts an object, it won't be memoized out of the box:
```js
constheavyMemoizedOperation=mem(heavyOperation);
heavyMemoizedOperation({full:true});// Stored in cache with the object as key
heavyMemoizedOperation({full:true});// Stored in cache with the object as key, again
// The objects look the same but for JS they're two different objects
```
You might want to serialize or hash them, for example using `JSON.stringify` or something like [serialize-javascript](https://github.com/yahoo/serialize-javascript), which can also serialize `RegExp`, `Date` and so on.
heavyMemoizedOperation('hello',{full:true});// Stored in cache with the key '["hello",{"full":true}]' (string)
heavyMemoizedOperation('hello',{full:true});// Retrieved from cache
```
#### Example: Multiple non-serializable arguments
If your function accepts multiple arguments that aren't supported by `JSON.stringify` (e.g. DOM elements and functions), you can instead extend the initial exact equality (`===`) to work on multiple arguments using [`many-keys-map`](https://github.com/fregante/many-keys-map):
cacheKey:arguments_=>arguments_,// Use *all* the arguments as key
cache:newManyKeysMap()// Correctly handles all the arguments for exact equality
});
addOneListener(header,'click',console.log);// `addListener` is run, and it's cached with the `arguments` array as key
addOneListener(header,'click',console.log);// `addListener` is not run again
addOneListener(mainContent,'load',console.log);// `addListener` is run, and it's cached with the `arguments` array as key
```
Better yet, if your function’s arguments are compatible with `WeakMap`, you should use [`deep-weak-map`](https://github.com/futpib/deep-weak-map) instead of `many-keys-map`. This will help avoid memory leaks.
Use a different cache storage. Must implement the following methods: `.has(key)`, `.get(key)`, `.set(key, value)`, `.delete(key)`, and optionally `.clear()`. You could for example use a `WeakMap` instead or [`quick-lru`](https://github.com/sindresorhus/quick-lru) for a LRU cache.
Returns a [decorator](https://github.com/tc39/proposal-decorators) to memoize class methods or static class methods.
Notes:
- Only class methods and getters/setters can be memoized, not regular functions (they aren't part of the proposal);
- Only [TypeScript’s decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#parameter-decorators) are supported, not [Babel’s](https://babeljs.io/docs/en/babel-plugin-proposal-decorators), which use a different version of the proposal;
- Being an experimental feature, they need to be enabled with `--experimentalDecorators`; follow TypeScript’s docs.
If you want to know how many times your cache had a hit or a miss, you can make use of [stats-map](https://github.com/SamVerschueren/stats-map) as a replacement for the default cache.
<a href="https://tidelift.com/subscription/pkg/npm-mem?utm_source=npm-mem&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.