Javascript缓存环,通过类切换方式来实现
2011-03-31 11:20
441 查看
定义一个固定尺寸的缓存,当它被填满时,新加入的元素会覆盖第一个(最老的)元素。一般情况我们会选择一个双头队列,可以从任意一头添加或删除数据。或者在运行时,根据缓存有没有满,去改变append函数的指向(方法切换)。但这里借用一下python中的self.__class__可以重新被指向一个新的类的思路(类切换),在javascript中实现一下。
<script>
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; delete this.append; delete this.tolist; this.__proto__ = new _full(); } } this.tolist = function(){ return this.data; } }
var x=new RingBuffer(5);
x.append(1);x.append(2);x.append(3);x.append(4);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
x.append(5);x.append(6);x.append(7);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
</script>
从未填满状态到填满状态的改变,会使实例的类进行切换,在python中可以通过对self.__class__的设置即可达到目的,但javascript中需要利用原型继承,来达到这一目的,上面的代码适用于firefox和chrome,对于IE,由于没有__proto__属性来引用原型对象(设置RingBuffer.prototype只会修改它自己原型对象的引用,不会修改已实例化对象的原型对象引用),所以当删除this中的方法后,由于找不到方法会报错。
对于IE,如果不能切换类,在javascript中,至少我们还能改变this的上下文
<script>
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; _full.call(this); } } this.tolist = function(){ return this.data; } }
var x=new RingBuffer(5);
x.append(1);x.append(2);x.append(3);x.append(4);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
x.append(5);x.append(6);x.append(7);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
</script>
到底是运行时进行方法切换,还是进行类切换,python cookbook上建议:方法切换在需要更细行为粒度控制时适合,而在成组的切换所有方法时,类切换可能最佳。
参考资料:python cookbook 6.11
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; delete this.append; delete this.tolist; this.__proto__ = new _full(); } } this.tolist = function(){ return this.data; } }
<script>
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; delete this.append; delete this.tolist; this.__proto__ = new _full(); } } this.tolist = function(){ return this.data; } }
var x=new RingBuffer(5);
x.append(1);x.append(2);x.append(3);x.append(4);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
x.append(5);x.append(6);x.append(7);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
</script>
从未填满状态到填满状态的改变,会使实例的类进行切换,在python中可以通过对self.__class__的设置即可达到目的,但javascript中需要利用原型继承,来达到这一目的,上面的代码适用于firefox和chrome,对于IE,由于没有__proto__属性来引用原型对象(设置RingBuffer.prototype只会修改它自己原型对象的引用,不会修改已实例化对象的原型对象引用),所以当删除this中的方法后,由于找不到方法会报错。
对于IE,如果不能切换类,在javascript中,至少我们还能改变this的上下文
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; _full.call(this); } } this.tolist = function(){ return this.data; } }
<script>
function RingBuffer( size_max ){ this.max = size_max; this.data = []; this.cur = 0; function _full(){ this.append = function( x ){ this.data[this.cur] = x; this.cur = ( this.cur + 1 ) % this.max; } this.tolist = function(){ return this.data.slice(this.cur).concat(this.data.slice(0,this.cur)); } } this.append = function( x ){ this.data[this.cur] = x; this.cur ++ ; if( this.cur == this.max ){ this.cur = 0; _full.call(this); } } this.tolist = function(){ return this.data; } }
var x=new RingBuffer(5);
x.append(1);x.append(2);x.append(3);x.append(4);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
x.append(5);x.append(6);x.append(7);
alert(x.tolist());
alert('x instanceof RingBuffer '+ (x instanceof RingBuffer).toString());
</script>
到底是运行时进行方法切换,还是进行类切换,python cookbook上建议:方法切换在需要更细行为粒度控制时适合,而在成组的切换所有方法时,类切换可能最佳。
参考资料:python cookbook 6.11
相关文章推荐
- JavaScript实现继承机制(3)——通过原型链(prototype chaining)方式
- html--通过javascript实现选项卡切换
- JavaScript实现Tab标签页切换的最简便方式
- JavaScript实现简单的图片轮播(通过点击数字切换)
- 通过AOP方式实现Service计算结果的缓存
- Android 通过自定义控件方式实现带开关效果的左右切换选择器。
- 如何通过js跨域调用ASP.NET Web API (请问如何实现在javascript中通过http get的方式跨域调用ASP.NET Web API?)
- JavaScript实现Tab标签页切换的最简便方式
- 通过CSS切换图片效果,点击这个图片可以实现连接功能,这里的图片在一张大图片中,每个并要切换的图片没有切换,通过disposition定位的方式做
- JavaScript实现简单的图片轮播(通过点击左右焦点切换)
- asp javascript 通过放大切换图片实现类似屏保效果
- 通过Javascript调用微软认知服务情感检测接口的两种实现方式
- Extending PhoneGap with native plugins for iOS (通过phonegap plugin的方式实现ios和javascript的互相调用)
- 最简单纯JavaScript实现Tab标签页切换的方式(推荐)
- [javascript]首页图片自动切换的一种实现方式
- 模仿微信朋友圈 仿微信js-sdk wx.previewImage javascript实现,支持图片预览,滑动切换,双指缩放,图片缓存 h5 html5 js
- 用自定义缓存区的方式实现文件的移动
- [原创]WCF后续之旅(10): 通过WCF Extension实现以对象池的方式创建Service Instance
- REST API下的ArcServer 9.3.0与9.3.1使用Javascript实现路径分析的不同方式