jQuery.data() 的实现方式
jQuery.data() 的实现方式
jQuery.data() 的作用是为普通对象或 DOM Element 附加(及获取)数据。
下面将分三个部分分析其实现方式:
1. 用name和value为对象附加数据;即传入三个参数,第一个参数为需要附加数据的对象,第二个参数为数据的名称,第三个参数为数据的值。当然,只是获取值的话,也可以不传入第三个参数。
2. 用另一个对象为对象附加数据;即传入两个参数,第一个参数为需要附加的数据对象(我们称之为“obj”),第二个参数也是一个对象(我们称之为“another”);“another”中包含的键值对将会被复制到 “obj” 的数据缓存(我们称之为“cache”)中。
3. 为 DOM Element 附加数据;DOM Element 也是一种 Object ,但 IE6、IE7 对直接附加在 DOM Element 上的对象的垃圾回收存在问题;因此我们将这些数据存放在全局缓存(我们称之为“globalCache”)中,即 “globalCache” 包含了多个 DOM Element 的 “cache”,并在 DOM Element 上添加一个属性,存放 “cache” 对应的 uid 。
用name和value为对象附加数据
使用 jQuery.data() 为普通对象附加数据时,其本质是将一个 “cache” 附加到了对象上,并使用了一个特殊的属性名称。
存放数据的 “cache” 也是一个 object,我们为 “obj” 附加的数据实际上成为了 “cache” 的属性。而 “cache” 又是 “obj” 的一个属性,在 jQuery 1.6中,这个属性的名称是 “jQuery16”加上一个随机数(如下面提到的 “jQuery16018518865841457738” )。
我们可以用下面的代码来测试 jQuery.data() 的功能:
<script type="text/javascript" src="jquery.js"></script><script>obj = {};$.data(obj, 'name', 'value');document.write("$.data(obj, 'name') = " + $.data(obj, 'name') + '<br />');for (var key in obj) {document.write("obj." + key + '.name = ' + obj[key].name);}</script>$.data(obj, 'name') = valueobj.jQuery16018518865841457738.name = value
$ = function() { var expando = "jQuery" + ("1.6" + Math.random()).replace(/\D/g, ''); function getData(cache, name) { return cache[name]; } function setData(cache, name, value) { cache[name] = value; } function getCache(obj) { obj[expando] = obj[expando] || {}; return obj[expando]; } return { data : function(obj, name, value) { var cache = getCache(obj); if (value === undefined) { return getData(cache, name); } else { setData(cache, name, value); } } }}();<script type="text/javascript" src="jquery.js"></script><script>obj = {};$.data(obj, {name1: 'value1', name2: 'value2'});document.write("$.data(obj, 'name1') = " + $.data(obj, 'name1') + '<br />' );document.write("$.data(obj, 'name2') = " + $.data(obj, 'name2') + '<br />');for (var key in obj) {document.write("obj." + key + '.name1 = ' + obj[key].name1 + '<br />');document.write("obj." + key + '.name2 = ' + obj[key].name2);}</script>$.data(obj, 'name1') = value1$.data(obj, 'name2') = value2obj.jQuery1600233050178663064.name1 = value1obj.jQuery1600233050178663064.name2 = value2
$ = function() { // Other codes ... function setDataWithObject(cache, another) { for (var name in another) { cache[name] = another[name]; } } // Other codes ... return { data : function(obj, name, value) { var cache = getCache(obj); if (name instanceof Object) { setDataWithObject(cache, name) } else if (value === undefined) { return getData(cache, name); } else { setData(cache, name, value); } } }}();<div id="div_test" /><script type="text/javascript" src="data.js"></script><script>window.onload = function() {div = document.getElementById('div_test');$.data(div, 'name', 'value');document.write($.data(div, 'name'));}</script>value
$ = function() { var expando = "jQuery" + ("1.6" + Math.random()).replace(/\D/g, ''); var globalCache = {}; var uuid = 0; // Other codes ... function getCache(obj) { if (obj.nodeType) { var id = obj[expando] = obj[expando] || ++uuid; globalCache[id] = globalCache[id] || {}; return globalCache[id]; } else { obj[expando] = obj[expando] || {}; return obj[expando]; } } // Other codes ...}();