JavaScript 中的记忆化 (Memoization)

2025 年 2 月 16 日 | 阅读 9 分钟

JavaScript 函数是任何编程语言不可或缺的一部分。作为开发人员,您可以在项目中频繁使用函数。可重用性是函数最重要的部分之一。您可以在程序执行期间随时联系我们。函数用于接受函数作为参数或返回函数。如果您的程序很大,它可能会多次使用函数。

在不断开发并开始执行日益复杂的计算的系统中,流程优化变得很有必要。它提高了系统中 Web 应用程序的速度要求。当忽略这个问题时,程序会消耗大量资源并需要一些时间来执行。

在本文中,您将学习记忆化,这种方法如果应用得当,可以帮助减少处理时间。

记忆化是如何工作的?

记忆化是一种自上而下、深度优先的优化策略,用于存储已经执行的计算。每次需要这些计算的结果时,软件都不需要再次执行计算。相反,初步调查的结果将被重新利用。因此,软件不再需要执行由于重复操作而耗时的计算。执行一项需要大量时间的活动需要很长时间。

这个想法与应用函数式编程有关。您会经常发现自己在一个程序中重复使用函数。记忆化用于在调用进程时临时存储其结果。任何需要此函数输出的计算都不需要运行两次。相反,它将使用上次运行的缓存结果。

在这种情况下,记忆化可以定义为一种缓存昂贵函数调用输出的技术,通过在重复相同输入时提供缓存结果来加速计算机程序。这些值不需要重新计算,因为记忆化将保留并检索它们。

记忆化的好处

  • 它是一种通过保存函数调用结果来提高性能的方法。它跟踪以前的结果并在程序执行期间按需检索它们。这缩短了执行时间,同时提高了 CPU 性能。
  • 一个记忆化的函数应该是一个纯函数。这意味着函数的执行方式保持不变。无论函数运行多少次,给定特定参数时,它都应该始终返回相同的值。
  • 为什么不将运行一次、两次甚至三次的函数的结果提交到内存中呢?这个函数只需要以这种方式使用一次。您的软件因此表现更好。
  • 何时在 JavaScript 中使用记忆化 纯函数是调用时始终提供相同值的函数。不纯的函数每次调用时都会返回不同的结果。如果这些数据被缓存,返回值可能会令人惊讶。
  • 缓存昂贵计算的结果可以使软件在执行时运行得更快。记忆化允许函数每次都能提供相同的结果,而无需用户重新计算其值。
  • JavaScript 中的记忆化用于防止对服务器进行多次请求。当远程发出重复的 API 调用时,它会阻止请求。
  • 您不必再进行另一次调用,因为您已经知道上一次调用是如何结束的,以获得相似的结果。
  • 递归函数使用循环输入值来重复自身。

记忆化过程

让我们来看一个实际情况,翻阅一本舒适、时尚且引人入胜的书。一个陌生人走过来问这本书是谁写的,书名是什么。您将翻到那一页,看到书名和作者姓名;之后,回复那个完全陌生的人。

更多人好奇想阅读更多关于这本书的信息,因为它太令人兴奋了。如果其他人走过来提问,您不会再次查看书名和作者。如果您不记得信息,那么您需要再次查找。那一刻您可能会回忆起细节。

JavaScript 中的记忆化过程取决于以下两个因素

  • 闭包
  • 高阶函数

闭包

在学习 JavaScript 中记忆化的闭包概念之前,我们必须学习词法作用域。词法作用域是变量的作用域,它定义了变量在源代码中的位置。

闭包函数是封闭函数及其对状态的引用的组合。它提供了从内部函数代码访问外部函数代码的权限。

闭包是在 JavaScript 中生成函数时生成的。它保留在内部函数源代码中的外部函数变量中。

闭包示例

以下示例展示了使用 JavaScript 的外部函数和内部函数的闭包函数。您可以将 solution_outer 和 solution_inner 函数与 js 变量中的记忆化一起使用。您将局部变量与内部函数一起使用,然后也命名源代码中存在的变量。

输出

输出显示了闭包函数的警告框。

Memoization in JavaScript

高阶函数

高阶函数是 JavaScript 函数,它们通过提供参数或将其作为输出返回来操作其他函数。要理解记忆化中的高阶函数,请学习斐波那契数列及其源代码。

高阶函数示例

以下示例展示了 JavaScript 中高阶函数的记忆化。您可以将给定函数的平方公式与输入参数一起使用。

输出

输出显示了记忆化函数的控制台日志。

Memoization in JavaScript

JavaScript 中记忆化的示例

我们可以看到使用不同函数和因素的多个记忆化示例。

示例 1

以下示例显示了带有缓存的记忆化函数。

输出

输出显示了记忆化函数的控制台日志。

Memoization in JavaScript

示例 2

以下示例显示了带有性能测试的记忆化函数。函数的默认流程用于测试 JavaScript 中记忆化函数的性能。

输出

输出显示了记忆化函数的控制台日志。

Memoization in JavaScript

示例 3

以下示例显示了带有记忆化函数的记忆化函数。记忆化函数是性能测试的因素之一。

输出

输出显示了记忆化函数的控制台日志。

Memoization in JavaScript

记忆化的递归函数

递归描述了一个多次调用自身的函数。指示何时停止调用自身的函数将定义一个中断条件。递归利用了循环的概念。当一个数字重复出现直到满足预定条件时,它就被认为处于循环中。

斐波那契数列很好地说明了递归。通过将数列中前两个数字相加,斐波那契数列预测下一个斐波那契项。

基本斐波那契数列示例

示例 1

以下示例展示了使用 JavaScript 的记忆化中的递归函数。您可以将斐波那契数列用于函数的递归。

输出

输出显示了斐波那契数列函数的控制台日志。

Memoization in JavaScript

示例 2

以下示例显示了具有递归功能的记忆化函数。我们可以使用 JavaScript 函数将斐波那契数列函数与记忆化变量一起使用。

输出

输出显示了记忆化函数的控制台日志。

Memoization in JavaScript

结论

您必须讨论 JavaScript 记忆化的解释。任何语言都可以从记忆化的编程概念中受益。其主要目标是使您的软件更好。当软件执行复杂的计算时,这一点尤其明显。