jquery使用data缓存数据
jquery使用data缓存数据一、$.data方法的语法
var cache = {};
$.data(cache,'key','value'); //缓存数据
//获取数据
$.data(cache,'key');
二、使用实例
1、$.hasData()用来判断某个对象是否有附加的属性,可以给任何JavaScript对象和HTMLElement对象附加属性。
2、$.data()用来读取或者修改属性值。
3、$.removeData()用来删除已经添加的属性,这是为了释放内存,避免过多无用属性浪费内存。
var myObj = {};
// hasData用来判断HTMLElement或JS对象是否具有数据
console.log(jQuery.hasData($("#a")));// false
// data()添加属性
$.data(myObj, 'name', 'aty');
console.log(jQuery.hasData(myObj));// true
// data()读取属性
console.log($.data(myObj, 'name'));//aty
// removeData删除属性
$.removeData(myObj, 'name');
console.log($.data(myObj, 'name'));//undefined
// 如果所有属性都被删除,那么hasData返回false
console.log(jQuery.hasData(myObj));// false
三、使用$.data数据缓存注意事项
1、因为jQuery缓存对象是全局的,在AJAX应用中,由于页面刷新很少,这个对象将一直存在,随着你对data的不断操作,很有可能因为使用不当,使得这个对象不断变大,最终影响程序性能。所以我们要及时清理这个对象,jQuery也提供了相应方法:removeData(name),name就是你当初设置data值时使用的name参数。
2、jQuery复制节点clone()方法不会复制data缓存,准确说jQuery不会在全局缓存对象中分配一个新节点存放新复制elem缓存。jQuery在clone()中把可能存在的缓存指向属性(elem的expando属性)替换成空。如果直接把这个属性复制,就会导致原先和新复制的elem都指向一个数据缓存,中间的互操作都将会影响到两个elem的缓存变量。
四、$.data数据缓存部分的源代码
/*********数据缓存模块****************************************/
//数据缓存模块的整体思路
//2.0.3版本的jQuery较之于1.7.3版本,使用面向对象的写法重构了数据缓存Data模块
//数据缓存模块的整体依据是:
//data_user和data_priv在一次运行期间只有对应的唯一对象,所有DOM元素的缓存都基于这两个实例对象完成
//data_user与data_priv这两个Data实例有各自的缓存对象属性cache,分别用于存储用户自定义数据和内部数据
//以data_user为例,在向对应的data_user对应的缓存对象cache中保存数据时,会为每个DOM元素分配一个唯一的id,该id作为该DOM元素的附加属性
//该唯一id(初始值为0,之后一次加1)会附加到DOM元素上,对应的DOM元素的属性名是data_user.expando,其对应的属性值就是id
//同时,会把该id作为属性名添加到data_user的缓存对象属性cache中,对应的属性值是一个都object对象,该对象称为DOM元素的数据缓存对象,其中存储着属性名和属性值的映射
//这样,通过分配唯一的id把DOM元素和该DOM元素的数据缓存对象关联起来
//data_priv与之类似
var data_priv,data_user,
rbrace=/^(?:\\{\\s\\S*\\}|\\[\\s\\S*\\])$/,//匹配json字符串格式,诸如{},或者[],不用.*进行匹配的原因是.不能匹配换行符
rmultiDash=/([A-Z])/g;//匹配任意的大写字母
function Data(){
//jQuery.expando是jQuery的静态属性,对于jQuery的每次加载运行期间时唯一的
//Math.random生成一个0-1之间的随机数
this.expando=jQuery.expando+Math.random();
this.cache={};
//这里采用访问器属性的写法
//常用的写法是Object.defineProperty(对象,对象属性,{[[get]],[[set]],[[configurable]],})
//这句话的目的,this.cache中的0属性是个只读属性
Object.defineProperty(this.cache,0,{
get:function(){
return {};
}
});
}
//下面可以看到,只有当accepts为false的时候,返回的id为0
Data.uid=1;
Data.accepts=function(owner){
//只有DOM元素,document元素,以及普通的js对象可以操作数据缓存
return owner.nodeType?owner.nodeType===1||owner.nodeType===9:true;
};
Data.prototype={
//获取(设置)owner对应的id,如果没有,则为其this.expando对应的属性,值为id,并未其在this.expando中创建缓存对象
key:function(owner){
if(!Data.accepts(owner)){
return 0;
}
var expando=this.expando,
id=owner[expando];
if(!id){
id=Data.uid++;
//为owner定义expando属性,为了保证该属性不可遍历且只读,使用访问器属性进行定义
//defineProperty一次只定义一个属性,接受三个参数,对象,属性名,属性描述对象
//defineProperties可以通过描述符一次定义多个属性,接受两个参数
//具体用法可以参照讲解http://www.tuicool.com/articles/ju26riE
Object.defineProperty(owner,expando,{
value:id,
});
}
if(!this.cache[id]){
this.cache[id]={};
}
return id;
},
//为DOM元素对应的缓存设置数据
//data参数可以是字符串,也可以是对象,当data是数组的时候,value可以不赋值
set:function(owner,data,value){
var id=this.key(owner),
//该DOM元素对应的缓存对象
cache=this.cache[id],
key;
if(typeof data==='string'){
cache[data]=value;
}else{
for(key in data){
cache[key]=data[key];
}
}
return cache;
},
//获取DOM元素owner对应缓存中属性key的值
//如果参数key不赋值,则代表去除owner对应的对象缓存
get:function(owner,key){
var id=owner[this.expando],
cache;
if(!id){
return undefined;
}
cache=this.cache[id];
return key?cache[key]:cache;
},
//设置或获取
access:function(owner,key,value){
var tmp;
if(!key||((key&&typeof key==='string') &&!value)){//说明是获取
//先尝试key本身,不行的话尝试转驼峰
tmp=this.get(owner,key);
return tmp? tmp: this.get(owner,jQuery.camelCase(key));
}
//否则说明是设置
this.set(owner,key ,value);
return value ? value : key;
},
//如果没有传入参数key,则移除DOM元素或者javascript元素关联的所有数据
//如果传入了参数key,则移除关联的指定名称的数据
//如果key是数组或者空格分割的多个数据名,则一次可以删除多个数据,删除的时候还需要尝试camel转换之后的形式
remove:function(owner,key){
var i,camel,length,
id=this.key(owner),
cache=this.cache[id];
if(!key){
this.cache[id]={};
标签: