浅谈js自记忆函数

更新日期: 2018-07-26阅读量: 1901标签: js知识

最近阅读《JavaScript忍者秘籍》看到了一种有趣的函数:自记忆函数


简介

何为自记忆函数?书中提到:

记忆化(memoization)是一种构建函数的处理过程,能够记住上次计算结果

通过这句话可以得出,自记忆函数其实就是能够记住上次计算结果的函数。在实现中,我们可以这样进行处理:当函数计算得到结果时,就将该结果按照参数存储起来。采取这种方式时,如果另外一个调用也使用相同的参数,我们则可以直接返回上次存储的结果而不是再计算一遍。

显而易见,像这样避免既重复又复杂的计算可以显著提高性能。对于动画中的计算、搜索不经常变化的数据或任何耗时的数学计算来说,记忆化这种方式是十分有用的。


一个自记忆函数的例子

下面这个例子展现自记忆函数的工作方式:

// 自记忆素数检测函数
function isPrime (value) {
  // 创建缓存
  if (!isPrime.answers) {
    isPrime.answers = {};
  }
  // 检查缓存的值
  if (isPrime.answers[value] !== undefined) {
    return isPrime.answers[value];
  }
  // 0和1不是素数
  var prime = value !== 0 && value !== 1;
  // 检查是否为素数
  for (var i = 2; i < value; i++) {
    if (value % i === 0) {
      prime = false;
      break;
    }
  }
  // 存储计算值
  return isPrime.answers[value] = prime
}

isPrime函数是一个自记忆素数检测函数,每当它被调用时:

首先,检查它的answers属性来确认是否已经有自记忆的缓存,如果没有,创建一个。

接下来,检查参数之前是否已经被缓存过,如果在缓存中找到该值,直接返回缓存的结果。

如果参数是一个全新的值,进行正常的素数检测。

最后,存储并返回计算值。


总结

自记忆函数有两个优点:

  • 由于函数调用时会寻找之前调用所得到的值,所以用户最终会乐于看到所获得的性能收益。
  • 它不需要执行任何特殊请求,也不需要做任何额外初始化,就能顺利进行工作。

但是,自记忆函数并不是完美的,它一样有着缺陷:

  • 任何类型的缓存都必然会为性能牺牲内存。
  • 很多人认为缓存逻辑不应该和业务逻辑混合,函数或方法只需要把一件事情做好。
  • 对自记忆函数很难做负载测试或估算算法复杂度,因为结果依赖于函数之前的输入。


来源:https://www.cnblogs.com/karthuslorin/archive/2018/07/25/9369066.html

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: https://www.fly63.com/article/detial/953

JavaScript中的循环和作用域

JavaScript有一个特点,也许会让开发者头痛, 是与循环和作用域相关的.const。最简单的方案是用 let 声明、另外一个非常普遍的解决这个问题是使用pre-ES6代码, 同时它被称作即时调用函数表达式(IIFE)

JS中的词法作用域(静态作用域)和动态作用域

首先说明一下,JavaScript没有用动态作用域概念,但 this 机制却和动态作用域类似!JavaScript是通过作用域链的方式进行变量查找的,而JS作用域链是词法作用域,也就做静态作用域!词法作用域:在函数声明(定义)时确定的

JS的变量作用域问题,理解js全局变量和局部变量问题

js的变量分为2种类型:局部变量和全局变量。主要区别在于:局部变量是指只能在变量被声明的函数内部调用,全局变量在整个代码运行过程中都可以调用。值得注意的js中还可以隐式声明变量,而隐式声明的变量千万不能当做全局变量来使用。

适配器在JavaScript中的体现

适配器设计模式在JavaScript中非常有用,在处理跨浏览器兼容问题、整合多个第三方SDK的调用,都可以看到它的身影。适配器模式是一种软件设计模式,允许从另一个接口使用现有类的接口。它通常用于使现有的类与其他类一起工作,而无需修改其源代码。

Js实现点击查看全文(类似今日头条、知乎日报效果)

这篇文章主要为大家详细介绍了原生JS+css仿QQ今日头条、知乎日报点击查看全文的效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下.

js的解析的两个阶段_预解析阶段、执行阶段

js不像C语言那样只要编译一次之后成.exe文件之后就不用在编译可以直接使用了,js是一种解释型语言,js同理是边解析边执行。js的解析分为两个阶段 1.预解析阶段 2.执行阶段。

js 实现栈和队列

js实现栈或者队列有两种方式: 1.数组:数组本身提供栈方法(push,pop),队列方法(push,shift)。 2.链表:构造链表结构,说白了就是链表的插入(尾插),移除(栈:末尾节点移除,队列:头结点移除)

js中delete关键字

delete关键字的作用:删除对象的属性 语法:delete 对象.属性、可以删除没有使用var关键字声明的全局变量(直接定义在window上面的属性)、删除数组元素、不能删除内置对象的属性、不能直接删除从原型上继承的属性

JavaScript中奇特的~运算符

本次分享一下并不是很常用的按位非运算符~的原理以及一点点用法。产生式 UnaryExpression : ~ UnaryExpression 按照下面的过程执行:令 expr 为解释执行 UnaryExpression 的结果。令 oldValue 为 ToInt32(GetValue(expr))。返回 oldValue 按位取反的结果。

js词法作用域和作用域的理解_什么是javascript词法作用域?

JavaScript引擎在代码执行前会对其进行编译:第一步编译阶段,第二步运行阶段。词法作用域:定义在词法阶段的作用域,即书写代码时函数声明的位置决定的。词法分析器处理代码时会保持作用域不变

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!