JavaScript基础函数的属性:记忆模式(019)
2014-09-17 00:03 Bryran 阅读(194) 评论(0) 编辑 收藏 举报函数在Javascript里是有属性的,因为它们是一种特殊对象。事实上,就算是没有明确声明,函数在最初就已经包含了一些固有的属性,比如所有函数都length这个属性,它可以指出函数声明了多少个参数:
function func(a, b, c) {} console.log(func.length); // 3
你 可以随时使用函数的属性。其中一个函数属性的用法是,把函数的返回值保存起来,方便下次执行时再使用,这就是函数的记忆模式。比如,下面的函数myFun 就声明了一个叫cache的属性,可以通过myFun.cache来访问,而cache又是一个对象,通过保存相应的键值对,保存myFun的执行结果:
var myFunc = function (param) { if (!myFunc.cache[param]) { var result = {}; // ... expensive operation ... myFunc.cache[param] = result; } return myFunc.cache[param]; }; // cache storage myFunc.cache = {};
上面的例子可以适用于函数使用一个参数的情况,如果函数接受多个参数,则可以先把这些参数变成JSON字符串,再把这个字符串作为Key来保存程序的执行结果:
var myFunc = function () { var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)), result; if (!myFunc.cache[cachekey]) { result = {}; // ... expensive operation ... myFunc.cache[cachekey] = result; } return myFunc.cache[cachekey]; }; // cache storage myFunc.cache = {};
这种做法有的缺点是,把参数变成JSON字符串后,它有对象“标识”就丢失了,这样,如果有两次执行过程中的参数是不同的对象,但它们的属性相同,那么只会为它们保存一个执行结果。
另一种完成相同功能的实现采用了arguments.callee,这种写法比较通用,不用把每个函数名都写出来。但ECMAScript 5 标准中并不支持arguments.callee。
var myFunc = function (param) { var f = arguments.callee, result; if (!f.cache[param]) { result = {}; // ... expensive operation ... f.cache[param] = result; } return f.cache[param]; }; // cache storage myFunc.cache = {};
参考: