JavaScript工厂模式的memoizing技术

折边加工

折边加工

2016-02-20 00:57

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

最近在读《JavaScript 设计模式》一书,其中工厂模式中提到了memoizing技术,今天仔细整理了一下memoization 相关的资料,与大家共享。

Memoization的定义:

memoization 一词是Donald Michie 根据拉丁语memorandum杜撰的一个词。相应的动词、过去分词、ing形式有memoiz、memoized、memoizing.

Memoization 是一种将函数返回值缓存起来的方法,Memoization 原理非常简单,就是把函数的每次执行结果都放入一个键值对(数组也可以,视情况而定)中,在接下来的执行中,在键值对中查找是否已经有相应执行过的值,如果有,直接返回该值,没有才 真正执行函数体的求值部分。很明显,找值,尤其是在键值对中找值,比执行函数快多了。现代 JavaScript 的开发也已经大量使用这种技术。

 一个简单的使用memoization的例子

我们知道,在不同的浏览器中,xmlHttpRequest对象的具体实现都不同。需要判断何种浏览器以执行具体的方法。这里就有一个使用memoization来实现的例子。

function createXHRObject = function(){     //先把三个匿名函数缓存起来。     var methods = [         function(){return new XMLHttpRequest();},         function(){return new ActiveXObject("Msxml2.XMLHTTP");},         function(){return new ActiveXObject("Microsoft.XMLHTTP");}     ];     for(var i=0,len=methods.length;ilen;i++){         try{//这里用try catch来代替了条件判断,通常我不赞成这种写法             methods[i]();         }         catch(e){             continue;//如果报异常,则执行下一次循环         }         // 把createXHRObject 与能正常执行的匿名函数对应起来,再调用createXHRObject不用再检测浏览器了         createXHRObject = method[i];         return method[i];     } }

以上是一个简单的例子,第一次执行createXHRObject()的时候,会循环判断methods 中的方法,获取一个能正确执行的,并将createXHRObject的引用指向这个方法。以后再使用这个方法的时候,不用去判断,直接自动获取正确的方法。这省去了频繁的ajax调用中浏览器的检测。

当然,这个方法看上去效率的提升不是特别明显,我之所以写上来,是因为能比较清晰的理解memoization是如何实现的。在递归调用的时候,memoization的威力才能更好的显现。

一个递归的例子

function fib(n) { if (n  2) { return n; } return fib(n - 1) + fib(n - 2); }

 这是一个经典的斐波纳契序列,fib(20) 会把fib这个方法执行21891次,如果是fib(40),这会执行331160281次。

再看看如何使用memoization来实现,

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/webkaifa/) var iterMemoFib = (function() {     var cache = [1, 1];     var fib = function(n) {         if (n = cache.length) {             //将一个递归转换成了一个             for (var i = cache.length; i = n; i++) {                 cache[i] = cache[i - 2] + cache[i - 1];             }         }         return cache[n-1];     }     return fib; })();

将Function的原型扩展memoize 和unmemoize 方法,这样你可以对任何函数实现memoize和解除memoize,当然,这个方法要慎,对一些不是频繁执行的函数,没必要缓存:

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/webkaifa/)Function.prototype.memoize = function() {     var pad  = {};     var self = this;     var obj  = arguments.length 0 ? arguments[i] : null;       var memoizedFn = function() {         // 把参数作为数组保存,作为键,把函数执行的结果作为值缓存起来         var args = [];         for (var i = 0; i arguments.length; i++) {             args[i] = arguments[i];         }         if (!(args in pad)) {             pad[args] = self.apply(obj, arguments);         }         return pad[args];     }     memoizedFn.unmemoize = function() {         return self;     }     return memoizedFn; } Function.prototype.unmemoize = function() {     alert("Attempt to unmemoize an unmemoized function.");     return null; }  

使用方法:

fib.memoize();

参考文档:

Memoizing functions in JavaScript JavaScript Memoization 提升JS性能:将递归转换为迭代 MemoizationFrom Wikipedia, the free encyclopedia
展开更多 50%)
分享

猜你喜欢

JavaScript工厂模式的memoizing技术

Web开发
JavaScript工厂模式的memoizing技术

PHP系列教程:设计模式介绍Ⅲ工厂模式

PHP
PHP系列教程:设计模式介绍Ⅲ工厂模式

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

C#设计模式编程之抽象工厂模式新解

编程语言 网络编程
C#设计模式编程之抽象工厂模式新解

《异星工厂》自由模式通关攻略

电脑网络
《异星工厂》自由模式通关攻略

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

JavaScript实现Iterator模式

Web开发
JavaScript实现Iterator模式

Javascript设计模式:观察者模式

Web开发
Javascript设计模式:观察者模式

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

解读javascript的计时器(翻译教程)

解读javascript的计时器(翻译教程)

win10斯巴达浏览器怎么清理浏览器缓存?

win10斯巴达浏览器怎么清理浏览器缓存?
下拉加载更多内容 ↓