javascript设计缓存系统

来源:互联网 发布:代练软件 编辑:程序博客网 时间:2024/06/09 19:52

 

 

本文使用JS来模仿jQuery,设计了一个缓存系统。像jQuery.data这样的东西,Prototype与mootools也有,目的都是用来辅助事件系统,用来缓存其中生成的数据,而非缓存普通函数上次计算的结果。Prototype利用了它的Hash类,mootools没细看,它内部好像用来缓存uuid。一个共识是,为页面用到的元素设置uuid非常有用,要查找元素时,可以避免重复查找,也可以用于与事件回调函数相绑定。由于uuid目前只有IE支持,它叫做uniqueID,格式为ms__id/d+,后面的数字也有名堂,叫做uniqueNumber。jQuery那个算是uniqueNumber吧,而且它的缓存系统非常复杂,支持缓存单个数据(利用data这个读写方法)与一组数据(利用queue,删除用dequeue)。没办法,因为它是白手起家,没有像Prototype那样利用一个自定数据类型分担一下职责。是时候进入正题,说一下我的缓存系统了。它利用到我的超级数组对象,实现像queue与dequeue。但我的超级数组对象能做的事更多,像filter,forEach,map,reduce,one,toObject,contains,remove等一应俱全.
下面看完整代码:

Code [http://www.xueit.com]
dom.eventTypes = dom.array(String("abort blur change click contextmenu /
dblclick error focus keydown keypress keyup load mousedown /
mouseenter mouseup mouseleave mousemove mouseover mouseout /
reset resize select submit unload
").match(//w /g));
//******************************缓存系统***********************
dom.mixin({
uuid :
0,
storage: {},
buildCache:
function(item){
var key,cache = dom.storage;
//如果是window
if ( item.setInterval && ( item !== window && !item.frameElement )) {
key
= "dom-window"
}
else if(item.nodeType){
if(!item.uuid){
item.uuid
= "dom" dom.uuid
dom.cache(
"uuid","uuid-set",item);//保存元素的引用
}//如果当前元素没有uuid这属性,那么为它添加一个
key = item.uuid
}
else if(dom.isString(item)){
key
= item;
}
else{
throw "item must be element node ,window or string"
}
if(!cache[key]){
cache[key]
= {};
}
return cache[key]
},
cache:
function(item,name,data){//读写缓存
var cache = dom.buildCache(item);
if(data !== undefined){
if(dom.isFunction(data)){//缓存函数,在函数设置一个uuid,生成方式取其toString()并去掉空白
var uuid = (data "").replace(//s /g,'');
data.uuid
= uuid;
}
if(!cache[name]){
//set与list允许缓存一组数据,
//其中如果带有-set后缀允许其中的元素重复,list则不允许
if(/-set$/.test(name)){//如果是第一次存储
cache[name] = array(data);
cache[name].type
= "set";
}
else if(/-list$/.test(name)){//
cache[name] = array(data);
cache[name].type
= "list";
}
else{
cache[name]
= data;
}
}
else{
var type = cache[name].type;
if(type && type === "set" ){
cache[name].ensure(data)
}
else if(type && type === "list" ){
cache[name].push(data)
}
else{
cache[name]
= data;
}
}
return item;
}
else{
return cache[name]
}
},
//参数可以为1,2,3
removeCache:function(item,name,data){
if(!arguments.length) return;
var cache = dom.buildCache(item),isDOM = !!item.nodeType;
if(isDOM && dom.eventTypes.contains(name)){
name
= name "-handlers-list";
};
if(arguments.length === 3){//移除指定的data
if(cache[name] instanceof dom.array && cache[name].length > 0){
//对于由事件绑定函数构成的超级数组,我们在缓存它的时候为每个函数设置了一个uuid
//现在我们比较现在传入的函数的uuid与超级数组中的某个元素的uuid是否相等
//如果有我们将得它的引用,有了它我们才能使用remove方法移除它。
if(dom.isFunction(data)){
var uuid = (data "").replace(//s /g,''),
fn
= cache[name].one(function(fn){
return fn.uuid == uuid;
});
if(fn){
cache[name].remove(fn);
}
}
else{
cache[name].remove(data);
}
if(cache[name].length === 0)
dom.removeCache(item,name);
}
else{
dom.removeCache(item,name);
}
}
else if(arguments.length === 2){//移除条目
delete cache[name]
if(!dom.isExtensible(cache)){
dom.removeCache(item);
}
}
else {
delete cache;
if(isDOM){
dom.removeCache(
"uuid","uuid-set",item);
dom.removeAttr(item,
"uuid");
}
}
},
clearCache:
function(){
var cache = dom.buildCache("uuid","uuid-set");
if(!cache) return;//如果为空直接返回
cache.forEach(function(el){
dom.removeAttr(el,
"uuid");
});
dom.storage
= null;
}


});
原创粉丝点击