JavaScript中的memorizing技术
今天看《JavaScript》设计模式第七章--工厂模式的时候接触到memorizing技术,简单的说就是对于某个方法,调用它的实例只在第一次调用它的时候才会进行方法中的计算,之后该实例再次调用该方法的时候就不在需要进行代码中的计算了,而是直接使用第一次调用时的计算结果。
先来看一段简单的代码,主要功能是用来得知今天星期几,当然要实现这功能完全不需要我这样复杂的代码,只是为了说明这技术。
function weekDay(){}; weekDay.prototype = { today: function(){ var a = this.getweekDay(); return a; }, getweekDay: function(){ var day = new Date().getDay(), str = "今天是周"; switch(day){ case 1: str += "一"; alert(str); break; case 2: str += "二"; alert(str); break; case 3: str += "三"; alert(str); break; case 4: str += "四"; alert(str); break; case 5: str += "五"; alert(str); break; case 6: str += "六"; alert(str); break; case 7: str += "日"; alert(str); break; default: break; }
// memorizing技术实现 this.getweekDay = function(){ return str; } return str; } };
我们在控制台中来测试一下:
var b = new weekDay(); b.today() //跳出alert窗口(“今天是周三”) //我们再运行一次 b.today() //没有跳出alert弹窗
可以看到第一次运行之后之后b再调用today方法不会再去走getweekDay中的switch语句,取而代之的是
this.getweekDay = function(){ return str; }
因为我们第一次调用的时候已经把结果写在了str中,并相当于重写了getweekDay方法。今天就是周三,之后没必要再去计算。当然你重新创建一个实例之后,调用today方法的时候还会去走getweekDay中的switch语句,因为对于该实例,是第一次调用这方法,还没有对getweekDay重写。
我们来看一看《JavaScript设计模式》中的代码
/* SimpleHandler class. */ var SimpleHandler = function() {}; // implements AjaxHandler SimpleHandler.prototype = { request: function(method, url, callback, postVars) { var xhr = this.createXhrObject(); xhr.onreadystatechange = function() { if(xhr.readyState !== 4) return; (xhr.status === 200) ? callback.success(xhr.responseText, xhr.responseXML) : callback.failure(xhr.status); }; xhr.open(method, url, true); if(method !== 'POST') postVars = null; xhr.send(postVars); }, createXhrObject: function() { // Factory method. 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; i < len; i++) { try { methods[i](); } catch(e) { continue; } // If we reach this point, method[i] worked. this.createXhrObject = methods[i]; // Memoize the method. return methods[i]; } // If we reach this point, none of the methods worked. throw new Error('SimpleHandler: Could not create an XHR object.'); } };
主要用于根据不同浏览器创建不同XHR对象,红字那一行就是memorizing技术的实现。可以想见如果不管方法中进行多么复杂的计算,之后再次调用的时候就能得到计算结果,没必要重新计算了。所以此后只有针对当前浏览器的代码会得到执行,假如前面的代码运行在一个支持XMLHttpRequest类的浏览器中,那么第二次执行时的createXhrObject方法实际上是这样的:
createXhrObject: ffunction() { return new XMLHttpRequest(); }
memorizing技术能够有效的提高代码效率,因为设置和检测代码只会执行一次。
参考资料:JavaScript设计模式(Ross Harmes / Dustin Diaz) 第七章--工厂模式