了解如何记忆 JavaScript 函数
那么,Memoization 到底是什么?
当再次接收到同一组输入时,无需重新计算即可返回先前计算的值的能力基本上就是记忆化。
因此,每当函数接收到同一组输入参数时,它都会检查其缓存变量中是否已经存在一个值,然后返回该值或重新计算。
- 它有助于减少计算时间。
- 更快的渲染时间
大纲:
- 有一个将两个数字相加的求和函数。
- 我们创建自己的
memoization
功能。 - 使用
memoization
函数作为高阶函数并创建输出函数。 - 当我们需要调用求和函数时,请调用上面的输出函数。
让我们开始吧。
Functionsummation
是我们要记忆的函数。
它是一个简单的函数,它将两个数字相加并返回结果。
// Function that sums two numbers
const summation = function (a, b) {
return a + b;
}
- 该
memoize
函数将一个函数fnToMemoize
作为单个参数,并返回一个function
可以调用的函数。 memoizedCache
是我们缓存新结果的对象。constructPropertyFromArgs
用于根据我们传递的参数和函数创建唯一的属性名称。我们将在下一节中详细了解这一点。manageInsertion
用于在达到最大大小时从缓存对象中删除属性。(默认长度:10)- 首先,我们检查该属性是否存在于中
memoizedCache
,如果是,我们从中返回结果,memoizedCache
或者我们实际调用该函数fnToMemoize
并将结果存储在中memoizedCache
。
// `memoize` function decides if it has to return cached value or call the summation function
const memoize = function (fnToMemoize) {
const memoizedCache = {} // A closeure Object
return function(...args) {
const propToCheck = constructPropertyFromArgs(fnToMemoize, args);
if (!memoizedCache[propToCheck]) {
memoizedCache[propToCheck] = fnToMemoize(...args);
} else {
console.log('From Cache ');
}
return memoizedCache[propToCheck];
}
}
我们如何构造属性名称?
这至关重要,因为不正确的命名可能会导致应用程序出现意外行为。
该memoize
函数可以充当通用函数,通过它我们可以记住位于同一范围内的任何其他函数。因此,为了避免不当行为,我们需要为函数设置唯一的名称。
我们的属性名称是函数名称和参数的组合,以“|”分隔,作为分隔符。
为什么我们需要分隔符?
假设我们不使用分隔符而只是连接字符串。
这里,的属性名称add (fn, 1, 2, 3)
将是fn123
。
并且,的属性名称add (fn, 12, 3)
也将是fn123
。
因此的输出add(fn, 12,3)
将是 6,这是根据上一次执行计算出来的。

// To create a Property name from the arguments passed to the function
const constructPropertyFromArgs = function (fnToMemoize, args) {
let propToCheck = [];
propToCheck = propToCheck.concat(fnToMemoize.name, args);
return propToCheck.join('|'); // A delimiter to join args
}
最后,我们将我们的summation
函数传递给memoize
返回存储在中的函数的函数memSummation
。
然后我们打了memSummation
两次电话。
const memSummation = memoize(summation, 2); // `memoize` is a HOC
console.log(memSummation(10, 50));
console.log(memSummation(10, 50));
输出:
第一个 console.log() 在执行后返回输出,而第二个则从缓存返回。
"From Summation function"
60
"From Cache "
60
这种方法的局限性:
- 不处理匿名函数
- 选择分隔符时应小心,因为对于与参数具有相同分隔符的字符串,它会失败。
- 仅适用于纯函数
- 无法控制空间复杂性。
考虑空间复杂度的示例在此博客中
CodePen 链接在这里
考虑空间复杂度的codepen 示例
在这里查看我的其他帖子
不要忘记关注我以查看有趣的帖子:)

就这样吧,大家 :)
鏂囩珷鏉ユ簮锛�https://dev.to/dhilipkmr/understand-how-to-memoize-a-javascript-function-3gal