memoization是一种非常有用的优化技术,它缓存特定输入产生的相应结果。这样麻烦的查找和迭代计算可以尽可能的减少。

它基本的思想是针对特定的输入,已经计算过的结果都是通过缓存当中的数据直接返回而不是经过重复的计算。

实现记忆函数

我们可以简单的将memoization理解为记忆函数经过特定输入产生的结果。

下面是一种基本简单且实用的实现方法,可以很清晰的显示记忆函数的结构

function memoize( fn ) {
return function () {
// 将参数转为数组
var args = Array.prototype.slice.call(arguments);
// 创建缓存对象在目标函数对象里
fn.cache = fn.cache || {};
// 如果缓存当中有相应的结果直接从缓存中返回,否则重新计算并存储缓存对象
return args in fn.cache ? fn.cache[args] : fn.cache[args] = fn.apply(this, args);
};
}

为了方便我们可以更形象的理解记忆函数,我们将上面的三目运算符改成if语句,并添加log。

function memoize( fn ) {
return function () {
// 将参数转为数组
var args = Array.prototype.slice.call(arguments);
// 创建缓存对象在目标函数对象里
fn.cache = fn.cache || {};
// 如果缓存当中有相应的结果直接从缓存中返回,否则重新计算并存储缓存对象
var results;
if (args in fn.cache) {
console.log('返回结果来自于缓存:');
results = fn.cache[args];
}else {
console.log('返回结果来自于函数计算:');
results = fn.cache[args] = fn.apply(this, args);
}
return results
};
}

实际使用

这里我们将其运用到实际中去,下面是一个计算最大公约数的函数。但它不是学习的要点,我们只要知道它接收两个数字,并返回他们的最大公约数。

// 这是一个计算最大公约数的函数
function gcd(a ,b){
var t;
if (a < b) t = b, b = a, a = t;
while(b != 0) t=b, b= a%b, a=t;
return a;
} var cachedGcd = memoize(gcd); console.log(cachedGcd(85, 187)); // 返回结果来自于函数计算: 17 console.log(cachedGcd(85, 187)); // 返回结果来自于缓存:

在上面这段代码,可以看到经memoize处理过的gcd函数便具备记忆缓存的作用。不只是gcd,对于任何特定输入产生特定结果的函数都可以使用记忆函数。

简单测试

使用time简单的测试一下非记忆时,和记忆时函数调用的时间。在不同的浏览器有不同的结果,但是,整体来看记忆时的时间是比非记忆时要短的。

console.time('non-memoized')
cachedGcd(85,187);
console.timeEnd('non-memoized')
console.time('memoized')
cachedGcd(85,187);
console.timeEnd('memoized')

由于gcd函数涉及的运算相对比较少,这还不能很明显的体现记忆函数的优势,试想一下,如果一个函数运算量很大很大。那么通过缓存返回的结果将直接跳过这些复杂的运算,迅速返回结果。

javascript高级知识点——memoization的更多相关文章

  1. JavaScript高级知识点整理

    一.JS中的数组 1.数组的三种定义方式 (1).实例化对象 var aArray=new Array(1,2,3,4,5); (2).快捷创建 var aTwoArray = [1,2,3,&quo ...

  2. javascript高级知识点——闭包

    代码信息来自于http://ejohn.org/apps/learn/. 先给出一个权威的定义,函数对象可以通过作用域相互关联起来,函数体内的变量可以保存在函数的作用域内,这种特性称为闭包. 在闭包内 ...

  3. javascript高级知识点——函数的长度

    代码信息来自于http://ejohn.org/apps/learn/. 函数的长度属性如何工作? function makeNinja(name){} function makeSamurai(na ...

  4. javascript高级知识点——指定上下文实现

    代码信息来自于http://ejohn.org/apps/learn/. 当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么? <ul id="results"&g ...

  5. javascript高级知识点——内置对象原型

    代码信息来自于http://ejohn.org/apps/learn/. 可以修改内置对象的方法. if (!Array.prototype.forEach) { Array.prototype.fo ...

  6. javascript高级知识点——继承

    代码信息来自于http://ejohn.org/apps/learn/. 继承是如何工作的 function Person(){} function Ninja(){} Ninja.prototype ...

  7. javascript高级知识点——实例类型

    代码信息来自于http://ejohn.org/apps/learn/. 分析一下对象的结构 function Ninja(){} var ninja = new Ninja(); console.l ...

  8. javascript高级知识点——函数原型

    代码信息来自于http://ejohn.org/apps/learn/. 向函数的原型中添加方法 function Ninja(){} Ninja.prototype.swingSword = fun ...

  9. javascript高级知识点——临时作用域

    代码信息来自于http://ejohn.org/apps/learn/. 自执行,临时,函数 (function(){ var count = 0; })(); 这是一个简单的自执行匿名函数. 做一个 ...

随机推荐

  1. [Spring入门学习笔记][Spring Boot]

    什么是Spring Boot Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...

  2. SQLserver 连接+开窗函数+视图+事务

    今天学习SQLserver 连接以及开窗函数..加油! 1.复习:查询(检索)->筛选列->筛选行:distinct top where 运算符与关键字:比较运算符,逻辑运算符,betwe ...

  3. MJRefresh(上拉加载下拉刷新)

    整理自:https://github.com/CoderMJLee/MJRefresh#%E6%94%AF%E6%8C%81%E5%93%AA%E4%BA%9B%E6%8E%A7%E4%BB%B6%E ...

  4. UINavigationController 导航控制器

    一.导航视图控制器 1.管理视图控制器 2.控制视图控制器之间的跳转 3.是以压栈和出栈的形式来管理视图控制器 4.导航视图控制器必须要设置根视图控制器 5.导航是视图控制器包含UINavigatio ...

  5. c#窗体的传值方法

    了解了窗体的显示相关知识,接着总结一下窗体的传值方法:  .通过构造函数  特点:传值是单向的(不可以互相传值),实现简单 实现代码如下: 在窗体Form2中         int value1;  ...

  6. 分享一个jdk源码链接

    请查看下面的链接:http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/bcba89ce0a8c/src/share/classes/,进入页面后,点击列表中 ...

  7. 给Array添加删除重复元素函数

    给Array本地对象增加一个原型方法,它用于删除数组中重复的元素(可能有多个重复), 返回值是一个包含被删除的重复条目的新数组. Array.prototype.distinct = function ...

  8. CSS3动画之旋转魔方盒

    步骤: 1.大盒子里盛放六个子盒子代表立方体的6个面: 2.子盒子开启3d效果  transform-style:preserve-3d; 3.上下面沿X轴旋转90度,一个上移盒子一半高,一个下移盒子 ...

  9. ie下没有背景色bug的解决方法

    鼠标经过下面的二级菜单的时候,在ie下面,收缩上去了,给这个二级菜单加了背景后,就是正常的,这个是ie下面的一个bug,解决方法:background-img:url(123.jpg):url里面的图 ...

  10. php缩放gif和png格式透明背景变成黑色的解决方法

    在对gif或png格式的图片进行缩放等操作时,原本透明背景的图片最后都变成黑色的,解决办法 $img = imagecreatetruecolor(, ); //2.上色 $color=imageco ...