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


Posted in Javascript onJune 08, 2011

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; 
<PRE class=brush:;gutter:true;><CODE>// data未定义,说明当前调用是查询数据,但是对象没有任何数据,直接返回 
if((!id || (pvt && id && !cache[id][internalKey])) && getByName && data === undefined) { 
return; 
} 
if(!id) { 
if(isNode) { 
// 用uuid种子递增分配唯一ID,只有DOM元素需要。因为需要存在全局cache中 
elem[jQuery.expando] = id = ++jQuery.uuid; 
} else { 
id = jQuery.expando; 
} 
} 
// 清空原来的值 
if(!cache[id]) { 
cache[id] = {}; 
if(!isNode) { 
cache[id].toJSON = jQuery.noop; 
} 
} 
// 用extend扩展cache,增加一个属性,用来保存数据 
if(typeof name === "object" || typeof name === "function") { 
if(pvt) { 
cache[id][internalKey] = jQuery.expand(cache[id][internalKey], name); 
} else { 
cache[id] = jQuery.extend(cache[id], name); 
} 
} 
thisCache = cahce[id]; 
// 避免Key冲突 
if(pvt) { 
if(!thisCache[internalKey]) { 
thisCahce[internalKey] = {}; 
} 
thisCache = thisCache[internalKey]; 
} 
if(data !== undefined) { 
thisCache[jQuery.camelCase(name)] = data; 
} 
return getByName ? thisCache[jQuery.camelCase(name)] : thisCache; 
} 
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; } 
<PRE class=brush:;gutter:true;><CODE>var internalCache = cache[ id ][ internalKey ]; 
// 如果还有数据,就清空一次再设置,增加性能 
if ( internalCache ) { 
cache[ id ] = {}; 
cache[ id ][ internalKey ] = internalCache; 
// 已经没有任何数据了,就全部删除 
} else if ( isNode ) { 
// 如果支持delete,就删除。 
// IE使用removeAttribute,所以尝试一次。再失败就只能设置为null了。 
if ( jQuery.support.deleteExpando ) { 
delete elem[ jQuery.expando ]; 
} else if ( elem.removeAttribute ) { 
elem.removeAttribute( jQuery.expando ); 
} else { 
elem[ jQuery.expando ] = null; 
} 
} 
}
Javascript 相关文章推荐
最佳6款用于移动网站开发的jQuery 图片滑块插件小结
Jul 20 Javascript
js模拟点击事件实现代码
Nov 06 Javascript
100个不能错过的实用JS自定义函数
Mar 05 Javascript
JavaScript手机振动API
Jun 11 Javascript
JavaScript判断是否是微信浏览器
Jun 13 Javascript
node.js中fs.stat与fs.fstat的区别详解
Jun 01 Javascript
JavaScript基础之this详解
Jun 04 Javascript
原生js封装添加class,删除class的实例
Nov 06 Javascript
WebSocket的通信过程与实现方法详解
Apr 29 Javascript
vuex进阶知识点巩固
May 20 Javascript
vue draggable resizable 实现可拖拽缩放的组件功能
Jul 15 Javascript
微信小程序学习之自定义滚动弹窗
Dec 20 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
Jun 08 #Javascript
jquery 跨域访问问题解决方法(笔记)
Jun 08 #Javascript
精通Javascript系列之数据类型 字符串
Jun 08 #Javascript
精通Javascript系列之Javascript基础篇
Jun 07 #Javascript
精通Javascript系列之数值计算
Jun 07 #Javascript
jQuery 源码分析笔记(4) Ready函数
Jun 02 #Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 #Javascript
You might like
关于尾递归的使用详解
2013/05/02 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
PHP调用Linux命令权限不足问题解决方法
2015/02/07 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
JQuery的Validation插件中Remote验证的中文问题
2010/07/26 Javascript
Jquery刷新页面背景图片随机变换的实现方法
2013/03/15 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
遍历js中对象的属性和值的实例
2016/11/21 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
angularjs中ng-bind-html的用法总结
2017/05/23 Javascript
关于vue单文件中引用路径的处理方法
2018/01/08 Javascript
详解element-ui日期时间选择器的日期格式化问题
2019/04/08 Javascript
150行Node.js实现的dns代理工具
2019/08/02 Javascript
对vue中的事件穿透与禁止穿透实例详解
2019/10/28 Javascript
Vue 实例中使用$refs的注意事项
2021/01/29 Vue.js
python 域名分析工具实现代码
2009/07/15 Python
解析Mac OS下部署Pyhton的Django框架项目的过程
2016/05/03 Python
在Linux命令行终端中使用python的简单方法(推荐)
2017/01/23 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
pycharm打开命令行或Terminal的方法
2019/01/16 Python
python画微信表情符的实例代码
2019/10/09 Python
美国高街时尚品牌:OASAP
2016/07/24 全球购物
EGO Shoes美国/加拿大:英国时髦鞋类品牌
2018/08/04 全球购物
Nebula美国官网:便携式投影仪
2019/03/15 全球购物
大学总结自我鉴定
2014/01/18 职场文书
违反校纪校规检讨书
2014/02/15 职场文书
大学生演讲稿
2014/04/25 职场文书
公司离职证明标准范本
2014/10/05 职场文书
党的群众路线教育实践活动整改落实情况报告
2014/10/28 职场文书
铣工实训报告
2014/11/05 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
2016参观监狱警示教育活动心得体会
2016/01/15 职场文书
JavaScript 中for/of,for/in 的详细介绍
2021/11/17 Javascript
浅谈Redis的事件驱动模型
2022/05/30 Redis