您的位置:首页 > Web前端 > JavaScript

Javascript缓存环,通过类切换方式来实现

2011-03-31 11:20 441 查看
定义一个固定尺寸的缓存,当它被填满时,新加入的元素会覆盖第一个(最老的)元素。一般情况我们会选择一个双头队列,可以从任意一头添加或删除数据。或者在运行时,根据缓存有没有满,去改变append函数的指向(方法切换)。但这里借用一下python中的self.__class__可以重新被指向一个新的类的思路(类切换),在javascript中实现一下。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐