深入理解jQuery.data() 的实现方式

2020-05-24 21:47:24易采站长站整理


$ = function() {
var expando = "jQuery" + ("6" + Mathrandom())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);
}
}
}
}();

function 中的第一行代码定义了 “expando” ,即 “jQuery1.6” 加上一个随机数(0.xxxx),并将其中非数字的部分去掉;这种格式将在jQuery的其他地方用到,这里不做探讨;只需要知道这是一个特殊的名称,并且可以用于标识不同的页面(比如不同 iframe 中的 “expando” 就会有所不同)。

接下来定义了获取数据的函数 getData(), 即从 “cache” 中获取一个属性;实际上也就是返回 cache[name] 。 

然后是 setData() 函数,用于设置 “cache” 的属性;实际上也就是设置 cache[name] 的值。 

之后是 getCache() , 获取 “obj” 上的 “cache”,即 obj[expando];如果 obj[expando] 为空,则进行初始化。 

最后公开了 data 方法,先根据传入的 “obj”,获取附加在 “obj” 上的 “cache”; 当传入两个参数时,调用 getData()方法;当传入三个参数时,则调用 setData() 方法。

用另一个对象为对象附加数据

除了以提供 name 和 value 的方式进行赋值,我们还可以直接传入另一个对象( “another” )作为参数。这种情况下,“another” 的属性名称和属性值将被视为多个键值对,从中提取的 “name” 和 “value” 都会被复制到目标对象的缓存中。

功能测试代码如下:


<script type="text/javascript" src="jqueryjs"></script>
<script>
obj = {};
$data(obj, {name1: 'value1', name2: 'value2'});

documentwrite("$data(obj, 'name1') = " + $data(obj, 'name1') + '<br />' );
documentwrite("$data(obj, 'name2') = " + $data(obj, 'name2') + '<br />');

for (var key in obj) {
documentwrite("obj" + key + 'name1 = ' + obj[key]name1 + '<br />');
documentwrite("obj" + key + 'name2 = ' + obj[key]name2);
}
</script>

显示结果如下:


$.data(obj, 'name1') = value1
$.data(obj, 'name2') = value2
obj.jQuery1600233050178663064.name1 = value1
obj.jQuery1600233050178663064.name2 = value2

上面的测试代码中,我们先将一个带有两个键值对的 “another” 对象传入,然后分别用 $.data(obj, ‘name1’) 和 $.data(obj, ‘name2’) 获取附加的数据;同样,为了深入了解其中的机制,我们通过遍历 “obj” 的方式取出了隐藏的 “cache” 对象,并获得了 “cache” 对象的 “name1” 属性和 “name2” 属性的值。