Heim > Web-Frontend > js-Tutorial > jQuery 源码分析笔记(6) jQuery.data_jquery

jQuery 源码分析笔记(6) jQuery.data_jquery

WBOY
Freigeben: 2016-05-16 18:06:00
Original
987 Leute haben es durchsucht

data部分的代码从1381行开始。最开始的几行关键代码:

复制代码 代码如下:

jQuery.extend({
// 存储数据的地方,关键实现核心
cache: { },
// 分配ID用的seed
uuid: 0,
// 为了区别不同的jQuery实例存储的数据,使用前缀+jQuery版本号+随机数作为Key
expando: "jQuery" + (jQuery.fn.jquery + Math.random()).replace(/\D/g, ""),
// 以下元素没有Data:embed和applet(这玩意还活着么),除了Flash之外的object。
noData: {
"embed": true,
"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
"applet": true
}
});

对外的接口都调用了两个内部函数:jQuery.data(elem, name, data, pvt)和jQuery.removeData(elem, name, pvt)。而removeData的逻辑与data类似,只是data是加入数据,而removeData使用delete或者设置为null删除数据。
data部分的代码中明确区分了JS对象和DOM对象的保存,这是为了解决部分浏览器的内存泄漏问题。在低版本IE中,当DOM和JS对象之间出现循环引用时,GC就无法正确处理。参见Understanding and Solving Internet Explorer Leak Patterns。至于COM对象,因为已经限制object元素没有data,就绕过了这个问题。
复制代码 代码如下:

data: function(elem, name, data, pvt) {
// 如果属于noData中定义的元素
if(!jQuery.acceptData(elem)) {
return;
}
var internalKey = jQuery.expando,
getByName = typeof name === "string",
thisCache,
isNode = elem.nodeType,
// DOM元素需要保存在Cache,JS对象直接保存到elem
cache = isNode ? jQuery.cache : elem,
// 如果elem的jQuery.expando已经有值了,就重用
id = isNode ? elem[jQuery.expando] : elem[jQuery.expando] && jQuery.expando;
<code>// data未定义,说明当前调用是查询数据,但是对象没有任何数据,直接返回 <br>if((!id || (pvt && id && !cache[id][internalKey])) && getByName && data === undefined) { <br>return; <br>} <br>if(!id) { <br>if(isNode) { <br>// 用uuid种子递增分配唯一ID,只有DOM元素需要。因为需要存在全局cache中 <br>elem[jQuery.expando] = id = ++jQuery.uuid; <br>} else { <br>id = jQuery.expando; <br>} <br>} <br>// 清空原来的值 <br>if(!cache[id]) { <br>cache[id] = {}; <br>if(!isNode) { <br>cache[id].toJSON = jQuery.noop; <br>} <br>} <br>// 用extend扩展cache,增加一个属性,用来保存数据 <br>if(typeof name === "object" || typeof name === "function") { <br>if(pvt) { <br>cache[id][internalKey] = jQuery.expand(cache[id][internalKey], name); <br>} else { <br>cache[id] = jQuery.extend(cache[id], name); <br>} <br>} <br>thisCache = cahce[id]; <br>// 避免Key冲突 <br>if(pvt) { <br>if(!thisCache[internalKey]) { <br>thisCahce[internalKey] = {}; <br>} <br>thisCache = thisCache[internalKey]; <br>} <br>if(data !== undefined) { <br>thisCache[jQuery.camelCase(name)] = data; <br>} <br>return getByName ? thisCache[jQuery.camelCase(name)] : thisCache; <br>} <br>removeData: function( elem, name, pvt ) { // 前面部分与data类似 // ... // 部分浏览器不支持在Element上进行delete操作,在jQuery.support中检查过这个浏览器特性。 // 如果delete失败的话,就先设置成null。 if ( jQuery.support.deleteExpando || cache != window ) { delete cache[ id ]; } else { cache[ id ] = null; } <br><pre class="brush:;gutter:true;"><code>var internalCache = cache[ id ][ internalKey ]; <br>// 如果还有数据,就清空一次再设置,增加性能 <br>if ( internalCache ) { <br>cache[ id ] = {}; <br>cache[ id ][ internalKey ] = internalCache; <br>// 已经没有任何数据了,就全部删除 <br>} else if ( isNode ) { <br>// 如果支持delete,就删除。 <br>// IE使用removeAttribute,所以尝试一次。再失败就只能设置为null了。 <br>if ( jQuery.support.deleteExpando ) { <br>delete elem[ jQuery.expando ]; <br>} else if ( elem.removeAttribute ) { <br>elem.removeAttribute( jQuery.expando ); <br>} else { <br>elem[ jQuery.expando ] = null; <br>} <br>} <br>} <br></code>
Nach dem Login kopieren
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage