装饰模式,让work函数本身不做任何修改的同,在其外部包裹一个额外的函数使其好像具备了新的额外的行为。
优点:1、装饰模式可以复用
优点:1、装饰模式可以复用
2、装饰模式可以灵活的组合
例子1
此处给work函数包裹外层函数后使其具有了一个日志功能,能记录并打印调用work时传递过的参数
function work(a,b){
//console.log(a+b);
return a+b;
}
function makeLogging(f){
var log = [];
function tempFun(){
log.push(arguments);
return f.apply(this,arguments);//此处的return比较有意义,在work无返回值时(实际返回undefined)和有返回值时都能保持和原work相同的功能。(当work无返回值时无return也能与之保持一致)
}
tempFun.outPutLog = function(){
for(var i=0;i<log.length;i++){
console.log([].join.call(log[i],","));//arguments不是数组,这里借用数组的join方法
}
}
return tempFun;
}
var work = makeLogging(work);
console.log(work(1,2));//3
console.log(work(2,3));//5
work.outPutLog();//1,2 2,3
例子2
//原理类似上边的例子
//一个生成随机数的函数rand,通过装饰模式使其具有传入相同的参数返回相同的随机数,
//并且有一个方法可以使这种机制重新开始
function rand(arg){
return Math.random() * arg;
}
function makeCache(f){
var cache = {};
function temp(arg){//检测cache中不存在新种子对应的随机数时,进行计算并将结果存入cache,每次返回cache中的值。以达到相同的种子返回相同的随机数
//static方法用于清空cache,重新进行缓存
if(!(arg in cache)){
cache[arg] = f.call(this,arg);
}
return cache[arg];
}
temp.flush = function(){
cache = {};
}
return temp;
}
rand = makeCache(rand);
console.log(rand(1));
console.log(rand(1));//相同的结果
rand.flush();
console.log(rand(1));//不同的结果