您的位置:首页 > Web前端 > JQuery

【菜鸟学习jquery源码】数据缓存与data()

2014-04-11 18:34 423 查看

前言

最近比较烦,深圳的工作还没着落,论文不想弄,烦。。。。。今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下。以后也打算把自己的jquery的学习心得写一个系列,当然和大神的源码分析是比不了的,只是自己在看的时候有好多地方是比较难理解的,为新手提供些便捷的学习方法,以后我会把我这些流水账整理成一个菜鸟学习jquery源码系列,现在就看到哪写到那,见谅。

内存泄露

首先看看什么是内存泄露,这里直接拿来Aaron中的这部分来说明什么是内存泄露,内存泄露的3种情况:

1 循环引用

2 Javascript闭包

3 DOM插入顺序

在这里我们只解释第一种情况,因为jquery的数据缓存就是解决这类的内存泄露的。一个DOM对象被一个Javascript对象引用,与此同时又引用同一个或其它的Javascript对象,这个DOM对象可能会引发内存泄漏。这个DOM对象的引用将不会在脚本停止的时候被垃圾回收器回收。要想破坏循环引用,引用DOM元素的对象或DOM对象的引用需要被赋值为null。

含有DOM对象的循环引用将导致大部分当前主流浏览器内存泄露

第一种:多个对象循环引用

jQuery.fn.extend({
data: function( key, value ) {
var attrs, name,
data = null,
i = 0,
elem = this[0];

// Special expections of .data basically thwart jQuery.access,
// so implement the relevant behavior ourselves

// Gets all values
if ( key === undefined ) {
if ( this.length ) {
data = jQuery.data( elem );

if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
attrs = elem.attributes;
for ( ; i < attrs.length; i++ ) {
name = attrs[i].name;

if ( name.indexOf("data-") === 0 ) {
name = jQuery.camelCase( name.slice(5) );

dataAttr( elem, name, data[ name ] );
}
}
jQuery._data( elem, "parsedAttrs", true );
}
}

return data;
}

// Sets multiple values
if ( typeof key === "object" ) {
return this.each(function() {
jQuery.data( this, key );
});
}

return arguments.length > 1 ?

// Sets one value
this.each(function() {
jQuery.data( this, key, value );//这是重点
}) :

// Gets one value
// Try to fetch any internally stored data first
elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
},


View Code

问题

现在我们利用源码分析一些问题

var a = $("body");
var b = $("body");
a.data("a",1);
b.data("a",2);
console.log(a.data("a"));//2
console.log(b.data("a"));//2

$.data(a,"b",1);
$.data(b,"b",2);
console.log($.data(a,"b"))//1
console.log($.data(b,"b"))//2

$.data(a[0],"b",1);
$.data(b[0],"b",2);
console.log($.data(a[0],"b"));//2
console.log($.data(b[0],"b"));//2


看着有些晕,先看下这个

var a = $("body");
var b = $("body");
console.log(a[0] == b[0]);//true
console.log(a == b);//false
console.log( $("body") == $("body"));//false


每一次$("body")都生成一个新的对象,所以每一次都会不同,$("body")[0]都是指向同一个body对象,a 和b指向的每个新对象的地址,所以不同。

看第一组

var a = $("body");
var b = $("body");
a.data("a",1);
b.data("a",2);
console.log(a.data("a"));//2
console.log(b.data("a"));//2


在看源代码这句

this.each(function() {
jQuery.data( this, key, value );
})


调用$.data(),但是这里第一个参数为this,是原生的DOM对象,第一组中的a和b的DOM对象都是body,所以添加数据会产生覆盖现象。

第二组和第二组是正常情况,不解释了。

小结

这就是我的理解,希望大家指正。以后会多分析jquery的实现过程,源码的细节太难了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: