0
# Function Memoization
1
2
Core memoization functionality that wraps functions to cache their results based on input arguments. Supports configurable argument handling, custom cache key generation, and multiple caching strategies for optimal performance across different use cases.
3
4
## Capabilities
5
6
### Basic Memoization
7
8
Creates a memoized version of any function with automatic result caching.
9
10
```javascript { .api }
11
/**
12
* Create a memoized version of a function
13
* @param {Function} fn - Function to memoize (required)
14
* @param {Object} options - Configuration options (optional)
15
* @returns {Function} Memoized function with additional cache methods
16
*/
17
function memoize(fn, options);
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
const memoize = require("memoizee");
24
25
// Simple function memoization
26
function fibonacci(n) {
27
if (n < 2) return n;
28
return fibonacci(n - 1) + fibonacci(n - 2);
29
}
30
31
const memoizedFib = memoize(fibonacci);
32
memoizedFib(40); // Computed once, then cached
33
34
// Function with multiple arguments
35
function multiply(a, b, c) {
36
return a * b * c;
37
}
38
39
const memoizedMultiply = memoize(multiply);
40
memoizedMultiply(2, 3, 4); // 24 (computed)
41
memoizedMultiply(2, 3, 4); // 24 (from cache)
42
```
43
44
### Argument Length Configuration
45
46
Control how many arguments are considered for cache key generation.
47
48
```javascript { .api }
49
/**
50
* Configure argument length handling
51
* @param {number|false} length - Number of arguments to consider, or false for dynamic
52
*/
53
const options = {
54
length: number | false
55
};
56
```
57
58
**Usage Examples:**
59
60
```javascript
61
// Fixed argument length (ignores extra arguments)
62
const memoized = memoize(fn, { length: 2 });
63
memoized("foo", 3, "ignored"); // Third argument ignored
64
memoized("foo", 3, "different"); // Cache hit
65
66
// Dynamic argument length (considers all arguments)
67
const dynamicMemoized = memoize(fn, { length: false });
68
dynamicMemoized("foo"); // Different cache entry
69
dynamicMemoized("foo", "bar"); // Different cache entry
70
```
71
72
### Primitive Mode
73
74
Optimized caching for functions with arguments that convert to unique strings.
75
76
```javascript { .api }
77
/**
78
* Enable primitive mode for string-convertible arguments
79
* @param {boolean} primitive - Use primitive mode optimization
80
*/
81
const options = {
82
primitive: boolean
83
};
84
```
85
86
**Usage Examples:**
87
88
```javascript
89
// Primitive mode for high-performance caching
90
const memoized = memoize(function(path) {
91
return fs.readFileSync(path, 'utf8');
92
}, { primitive: true });
93
94
memoized("/path/to/file.txt"); // String argument, fast hash lookup
95
memoized("/path/to/file.txt"); // Cache hit with O(1) access
96
```
97
98
### Custom Normalizers
99
100
Define custom cache key generation logic for complex argument patterns.
101
102
```javascript { .api }
103
/**
104
* Custom cache key normalization function
105
* @param {Function} normalizer - Function that generates cache keys from arguments
106
*/
107
const options = {
108
normalizer: function(args) {
109
// Return string key based on arguments object
110
return string;
111
}
112
};
113
```
114
115
**Usage Examples:**
116
117
```javascript
118
// Normalize object arguments by content
119
const memoized = memoize(function(config) {
120
return processConfig(config);
121
}, {
122
normalizer: function(args) {
123
return JSON.stringify(args[0]);
124
}
125
});
126
127
memoized({ api: "v1", timeout: 5000 });
128
memoized({ timeout: 5000, api: "v1" }); // Different order, same cache key
129
130
// Deep object normalization with sorted keys
131
const deepNormalizer = memoize(expensiveFunction, {
132
normalizer: function(args) {
133
const sortedEntries = (obj) =>
134
Object.entries(obj)
135
.map(([key, value]) => [
136
key,
137
value && typeof value === "object" ? sortedEntries(value) : value
138
])
139
.sort();
140
return JSON.stringify(sortedEntries(args[0]));
141
}
142
});
143
```
144
145
### Argument Resolvers
146
147
Pre-process function arguments before cache key generation and function execution.
148
149
```javascript { .api }
150
/**
151
* Argument resolver functions for type coercion
152
* @param {Function[]} resolvers - Array of functions to transform arguments
153
*/
154
const options = {
155
resolvers: [Function, ...]
156
};
157
```
158
159
**Usage Examples:**
160
161
```javascript
162
// Type coercion for consistent caching
163
const memoized = memoize(function(str, bool) {
164
return str.repeat(bool ? 2 : 1);
165
}, {
166
length: 2,
167
resolvers: [String, Boolean]
168
});
169
170
memoized(12, 1); // "1212"
171
memoized("12", true); // Cache hit - resolved to same arguments
172
memoized({ toString: () => "12" }, {}); // Cache hit - also resolves the same way
173
```
174
175
### Force Re-memoization
176
177
Override existing memoization on already memoized functions.
178
179
```javascript { .api }
180
/**
181
* Force memoization of already memoized functions
182
* @param {boolean} force - Override existing memoization
183
*/
184
const options = {
185
force: boolean
186
};
187
```
188
189
**Usage Examples:**
190
191
```javascript
192
const fn = function(x) { return x * 2; };
193
const memoized1 = memoize(fn, { maxAge: 1000 });
194
const memoized2 = memoize(memoized1, { maxAge: 5000, force: true });
195
196
// Without force: true, memoized1 would be returned unchanged
197
// With force: true, creates new memoization with different options
198
```
199
200
## Memoized Function Properties
201
202
### Cache Identification
203
204
```javascript { .api }
205
/**
206
* Property indicating function is memoized
207
* @type {boolean}
208
*/
209
memoizedFunction.__memoized__ = true;
210
```
211
212
### Cache Management Methods
213
214
```javascript { .api }
215
/**
216
* Delete cached result for specific arguments
217
* @param {...any} args - Arguments to delete from cache
218
*/
219
memoizedFunction.delete(...args);
220
221
/**
222
* Clear all cached results
223
*/
224
memoizedFunction.clear();
225
226
/**
227
* Get cached value without triggering function execution
228
* @param {...any} args - Arguments to lookup
229
* @returns {any} Cached value or undefined
230
*/
231
memoizedFunction._get(...args);
232
233
/**
234
* Check if arguments have a cached result
235
* @param {...any} args - Arguments to check
236
* @returns {boolean} True if cached result exists
237
*/
238
memoizedFunction._has(...args);
239
```
240
241
**Usage Examples:**
242
243
```javascript
244
const memoized = memoize(expensiveFunction);
245
246
// Cache management
247
memoized(1, 2); // Execute and cache
248
memoized._has(1, 2); // true
249
memoized._get(1, 2); // Returns cached value
250
memoized.delete(1, 2); // Remove from cache
251
memoized._has(1, 2); // false
252
253
// Clear entire cache
254
memoized(1, 2);
255
memoized(3, 4);
256
memoized.clear(); // All entries removed
257
```
258
259
## Performance Considerations
260
261
### Choosing Cache Strategies
262
263
- **Primitive mode**: Use when arguments convert to unique strings (paths, IDs, simple values)
264
- **Object mode**: Use when arguments are complex objects or when primitive conversion isn't unique
265
- **Custom normalizers**: Use when you need specific cache key logic or object content comparison
266
267
### Memory Management
268
269
```javascript
270
// For functions with potentially unlimited inputs
271
const memoized = memoize(fn, {
272
max: 1000, // Limit cache size
273
dispose: (value) => { // Cleanup when entries are evicted
274
if (value && value.cleanup) value.cleanup();
275
}
276
});
277
```
278
279
### Argument Length Optimization
280
281
```javascript
282
// More efficient when you know exact argument count
283
const memoized = memoize(fn, { length: 3 });
284
285
// Use false only when argument count varies significantly
286
const variadic = memoize(fn, { length: false });
287
```