JavaScript工厂模式的memoizing技术

2016-02-20 00:57 12 1 收藏

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

【 tulaoshi.com - Web开发 】

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

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/webkaifa/)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调用中浏览器的检测。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/webkaifa/)

当然,这个方法看上去效率的提升不是特别明显,我之所以写上来,是因为能比较清晰的理解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来实现,

 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,当然,这个方法要慎,对一些不是频繁执行的函数,没必要缓存:

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

来源:https://www.tulaoshi.com/n/20160220/1632906.html

延伸阅读
标签: Web开发
秦歌(YanKaven) 的站点:http://dancewithnet.com/ 全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。 Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益...
标签: Web开发
作者: Abhijeet Bhattacharya (abhbhatt@in.ibm.com), 系统软件工程师, IBM India Kiran Shivarama Shivarama Sundar (kisundar@in.ibm.com), 系统软件工程师, IBM India 2007 年 5 月 28 日 如果您知道内存泄漏的起因,那么在 JavaScript 中进行相应的防范就应该相当容易。在这篇文章中,作者 Kiran Sundar 和 Abhijeet Bhattacharya 将带...
利用设计模式可以使我们的代码更灵活,更容易扩展,更容易维护。各种面向对象的程序设计语言都提供了基本相同的机制:比如类、继承、派生、多态等等。但是又有各自的特色,C# 中的反射机制便是一个很重要的工具,好好地利用就可以在实际中发挥很大的作用。 我们来看一个例子: 我的程序中有需要一系列的对象,比如apple,orange, ...
标签: Web开发
基于web的技术中,分页是一个老的不能再老的,但大家津津乐道的问题,随着xml技术的日渐应用,把xml应用到分页当中,也是一种可能,当然网上的教程很多,当我都是看得稀里糊涂,索性自己写一个,与大家分享、指正。 共有两个文件tmh.htm & tt.xml 源代码如下: tmh.htm ___________________________________________________ !DOCTYPE ...
标签: Web开发
一、首先需要配置WEB服务器 在设计WAP网页时不论你使用的WAP开发工具是UP.SDK 或NOKIA WAP TOOKIT 或者ERICSSON WAPIDE,你都必须进行WEB服务器设置,故在此将常见的几种WEB服务器的设置介绍如下:(这里用的是Tomcat4.0,即Apache Web Server.设置方法如下:) 环境:Apache Web Server on NT OR Solaries OR LINUX OR OTHER UN...

经验教程

871

收藏

49
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部