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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM