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

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

可以看到,jQuery.data() 实际上为 “obj” 附加了名为 “obj.jQuery1600233050178663064” 的对象,也就是 “cache” 上。用 jquery.data() 方式传入的键值对都被复制到了 “cache” 中。

我们可以用下面的代码实现类似的功能:


$ = 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);
}
}
}
}();

这段代码是在之前的代码的基础上进行修改的。首先增加了内部函数 setDataWithObject() ,这个函数的实现是遍历 “another” 的属性,并复制到 “cache” 中。 

然后,在对外开放的 data 函数中,先判断传入的第二个参数的名称,如果这个参数是一个 Object 类型的实例,则调用 setDataWithObject() 方法。

为 DOM Element 附加数据

由于 DOM Element 也是一种 Object,因此之前的方式也可以为 DOM Element 赋值;但考虑到 IE6、IE7 中垃圾回收的问题(不能有效回收 DOM Element 上附加的对象引用),jQuery采用了与普通对象有所不同的方式附加数据。

测试代码如下:


<script type="text/javascript" src="datajs"></script>
<script>
windowonload = function() {
div = documentgetElementById('div_test');
$data(div, 'name', 'value');
documentwrite($data(div, 'name'));
}
</script>

显示结果如下:


value

测试代码中,首先通过 document.getElementById 方法获取了一个 DOM Element (当然,也可以用 jQuery 的选择器),然后在这个 DOM Element 上附加了一个属性,随后就从 DOM Element 上取出了附加的属性并输出。

因为考虑到 IE6、IE7 对 DOM Element 上的对象引用的垃圾回收存在问题,我们不会直接在 DOM Element 上附加对象;而是使用全局cache,并在 DOM Element 上附加一个 uid。

实现方式如下:


$ = function() {
var expando = "jQuery" + ("6" + Mathrandom())replace(/D/g, '');
var globalCache = {};
var uuid = 0;

// Other codes

function getCache(obj) {
if (objnodeType) {
var id = obj[expando] = obj[expando] || ++uuid;
globalCache[id] = globalCache[id] || {};
return globalCache[id];
} else {
obj[expando] = obj[expando] || {};
return obj[expando];
}