jQuery数据缓存方案详解:$.data()的使用

Posted 盛开的雨季

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jQuery数据缓存方案详解:$.data()的使用相关的知识,希望对你有一定的参考价值。

我们经常使用隐藏控件或者是js全局变量来临时存储数据,全局变量容易导致命名污染,隐藏控件导致经常读写dom浪费性能。jQuery提供了自己的数据缓存方案,能够达到和隐藏控件、全局变量相同的效果,但是jQuery实现方式更优雅。为了更好地使用jQuery数据缓存方案,我们需要掌握$.data()、$.cache、$.expando、$.hasData()、$.removeData()。

 

$.hasData()用来判断某个对象是否有附加的属性,可以给任何JavaScript对象和htmlElement对象附加属性。$.data()用来读取或者修改属性值。$.removeData()用来删除已经添加的属性,这是为了释放内存,避免过多无用属性浪费内存。

[javascript] view plain copy
 
  1. var myObj = {};  
  2. // hasData用来判断HTMLElement或JS对象是否具有数据  
  3. console.log(jQuery.hasData($("#a")));// false  
  4.   
  5. // data()添加属性  
  6. $.data(myObj, \'name\', \'aty\');  
  7. console.log(jQuery.hasData(myObj));// true  
  8.   
  9. // data()读取属性  
  10. console.log($.data(myObj, \'name\'));//aty  
  11.   
  12. // removeData删除属性  
  13. $.removeData(myObj, \'name\');  
  14. console.log($.data(myObj, \'name\'));//undefined  
  15.   
  16. // 如果所有属性都被删除,那么hasData返回false  
  17. console.log(jQuery.hasData(myObj));// false   

 

给HTMLElement对象添加属性,使用方式跟为普通js对象添加属性一模一样。

[html] view plain copy
 
  1. <div id="content"></div>  
  2. <script>  
  3.     var el = document.getElementById(\'content\');  
  4.     $.data(el, \'name\', \'aty\');  
  5.     console.log($.data(el, \'name\')); // aty  
  6. </script>  

 

 

可以看到使用jQuery数据缓存的API是很容易的,现在我们要大致看下jQuery是如何实现缓存方案。为普通JS对象提供缓存时,jquery直接将数据保存在原始的JS对象上。此时会偷偷的给JS对象添加个属性(类似于jQuery16101803968874529044),属性值也是一个对象。

[javascript] view plain copy
 
  1. var myObj = {};  
  2. $.data(myObj, \'name\', \'aty\');  
  3. console.log(myObj);  
  4. console.log($.expando);  

 

我们可以看到myObj结构发生了变化:jquery给普通对象偷偷添加的属性名称其实就是$.expando。

jQuery.expando是一个字符串,使用Math.random生成,去掉了非数字字符。它作为HTMLElement或JS对象的属性名。页面引入jQuery框架的时候,会随机生成一个字符串。

[javascript] view plain copy
 
  1. expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, "" ),  


现在我们知道了jQuery如何给普通对象添加属性,以及expando的含义,那么我们就可以通过下面的代码获取添加的属性。

[javascript] view plain copy
 
  1. var hisObj = {};  
  2. $.data(hisObj, \'name\', \'him\');  
  3. console.log(hisObj[jQuery.expando].data.name);//him  

 

 

为HTMLElement提供缓存时,却不会直接保存在HTMLElement上。而是保存在jQuery.cache这个全局对象上。此时先给HTMLElement添加属性(jQuery.expando),属性值为数字(1,2,3递增)。即只将一些数字保存在了HTMLElement上,不会直接将数据置入。这是因为IE老版本中可能会存在内存泄露危险。而HTMLElement如何与jQuery.cache建立联系呢? 还是id。刚刚提到属性值数字就是id。

[html] view plain copy
 
  1. <div id="a"></div>  
  2. <script>  
  3. var dom = document.getElementById("a");  
  4. $.data(dom, \'name\', \'aty\');  
  5. console.log(dom[jQuery.expando]); // 1  
  6. console.log(jQuery.cache); // {1 : {data:{name:\'aty\'}}}  
  7. </script>  


知道了jQuery如何为dom对象添加属性,我们就可以通过下面的代码获取属性。

[javascript] view plain copy
 
  1. console.log(jQuery.cache[dom[jQuery.expando]].data.name);   



 

现在我们看下DOM对象和jQuery封装后的对象有什么区别。

[javascript] view plain copy
 
  1. // 给dom元素添加数据  
  2. var dom = document.getElementById("a");  
  3. $.data(dom, \'name\', \'aty\');  
  4. console.log(jQuery.hasData(dom));//true  
  5. console.log($.data(document.getElementById("a"), \'name\'));//aty  
  6. console.log($.data($("#a")[0], \'name\'));//aty  
  7.   
  8. // 给jquery包装后的dom附加对象  
  9. var $dom = $("#a");  
  10. $.data($dom, \'age\', \'25\');  
  11. console.log(jQuery.hasData($dom));//true  
  12. console.log($.data($dom, \'age\'));//25  
  13. console.log($.data($("#a"), \'age\'));//undefined  


这是因为本质区别在于:原始的DOM对象会被jQuery特殊对待,而jQuery包装后的对象与普通JS对象无异。通过jQuery选择器每次获取的对象并不是同一个对象

[javascript] view plain copy
 
  1. var $dom = $("#a");  
  2. $.data($dom, \'age\', \'25\');  
  3.   
  4. // dom对象支持多次获取,jQuery对象不支持  
  5. console.log( document.getElementById("a") ===  document.getElementById("a"));///true  
  6. console.log( document.getElementById("a") ===  $("#a")[0]);///true  
  7. console.log($("#a") ===  $("#a"));//false  
  8.   
  9. // jQuery包装后的对象,与普通javascript对象无异  
  10. console.log($dom[jQuery.expando].data.age);//25  


最后再提一下,可以使用$.data获取某个对象上附加的所有属性。

[javascript] view plain copy
    1. var $dom = $("#a");  
    2. $.data($dom, \'age\', \'25\');  
    3.   
    4. console.log($.data($dom));//Object {age: "25"}  

参考文章:

读jQuery之六(缓存数据) 

http://www.cnblogs.com/weihengblogs/p/6093067.html

以上是关于jQuery数据缓存方案详解:$.data()的使用的主要内容,如果未能解决你的问题,请参考以下文章

jQuery1.9.1源码分析--数据缓存Data模块

jQuery数据缓存$.data 的使用以及源码解析

jQuery11 data() : 数据缓存

数据缓存Data

数据缓存Data

jQuery缓存数据