利用这个类可以保存方法的的实参,函数以后备用。在实例生成时会产生一个序列号用来标识是否来自undo或者redo的调用,从而避免存入缓存栈。
在浏览器中用调试工具看调用结果
View Code
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 6 <title>javascript</title> 7 </head> 8 9 <body> 10 <input type="button" value=" - " id="a" /> <input type="button" value=" + " id="b" /> 11 12 <input type="button" value=" - " id="c" /> <input type="button" value=" + " id="d" /> 13 <script type="text/javascript"> 14 /*function a() { 15 Do([].slice.call(arguments)); 16 } 17 function Do() { 18 var temp = (arguments[0]),indicator = arguments.callee; 19 indicator.stack = []; 20 indicator.stack[0] = temp; 21 } 22 a({c:1,b:2}, 123, function(arg) { 23 return arg+1; 24 }); 25 function dir() { 26 console.log(arguments[0]); 27 } 28 dir(Do.stack[0][2](3));*/ 29 30 function MemoryDo(step){ 31 32 var indicator,that,fn,slice,args; 33 ( 34 indicator=arguments.callee, 35 slice=[].slice 36 ) 37 if(!(this instanceof indicator)){return new indicator(step);} 38 39 indicator.keys={}; 40 that=this; 41 this.stack=[]; 42 this.index=0; 43 44 45 fn = indicator.prototype; 46 fn.constructor = indicator; 47 48 fn.is=function(o){ 49 return ({}).toString.call(o).slice(8, -1); 50 } 51 fn.slice=function(o,index){ 52 return slice.call(o,index || 0); 53 } 54 fn.setIndex=function(number){ 55 if(number<0 || this.is(this.index)!=='Number'){return}; 56 this.index=number; 57 } 58 fn.getIndex=function(){ 59 return this.is(this.index)==='Number' ? this.index : null; 60 } 61 fn.sign=function(){ 62 return ('abcdefghijk'[Math.random().toFixed(1) * 10]+this.randomNumber(10000,10000000)); 63 } 64 fn.randomNumber=function(a,b){ 65 return Math.round(Math.random()*b+a); 66 } 67 fn.dataBuffer=function(){ 68 var temp,socureCall=arguments.callee.caller,flag=arguments[0][arguments[0].length-1],data; 69 if (socureCall.arguments.length !== arguments[0].length || indicator.keys[flag]==='used') return; 70 71 data=this.stack; 72 if(data.length===this.step){data.shift()}; 73 74 temp=data[data.length]=[]; 75 temp[temp.length]=(this.slice(arguments[0],0)).concat(this.sn); 76 temp[temp.length]=arguments.callee.caller; 77 78 indicator.keys[this.sn]='used'; 79 80 this.index=this.stack.length; 81 } 82 fn.redo=function(){ 83 //var data=indicator.stack[indicator.stack.length-1]; 84 //console.log(data); 85 if(this.index===this.stack.length){ 86 this.re=-1;return; 87 }else{ 88 this.re=1; 89 this.virtualDo(this.index+=1); 90 } 91 92 } 93 fn.undo=function(){ 94 //var data=indicator.stack[indicator.stack.length-1]; 95 //console.log(data); 96 97 if(this.index===0){ 98 return; 99 }else{ 100 this.un=1; 101 this.virtualDo(this.index-=1); 102 } 103 104 } 105 fn.virtualDo=function(){ 106 var data=this.stack,i=0,len=this.index,temp; 107 for(;i<len;){ 108 temp=data[i++]; 109 temp[1].apply(undefined,temp[0]); 110 } 111 } 112 113 114 this.step=this.is(step)==='Number'? step : 10; 115 this.sn=this.sign(); 116 117 } 118 119 120 var a=MemoryDo(4); 121 var b=MemoryDo(2); 122 function doIt(o,fn){ 123 a.dataBuffer(arguments); 124 125 fn(arguments); 126 b.dataBuffer(arguments); 127 } 128 doIt({a:1,b:2,c:3},function(a){ 129 console.dir(a); 130 }); 131 doIt({b:2,c:3},function(a){ 132 console.dir(a); 133 }); 134 doIt({c:3},function(a){ 135 console.dir(a); 136 }); 137 doIt({d:4},function(a){ 138 console.dir(a); 139 }); 140 document.getElementById('a').onclick=function(){ 141 a.undo(); 142 } 143 document.getElementById('b').onclick=function(){ 144 a.redo(); 145 } 146 document.getElementById('c').onclick=function(){ 147 b.undo(); 148 } 149 document.getElementById('d').onclick=function(){ 150 b.redo(); 151 } 152 </script> 153 </body> 154 </html>
来源:https://www.cnblogs.com/enix/archive/2011/12/08/2281309.html