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 相关文章推荐
Javascript Global对象
Aug 13 Javascript
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
Apr 13 Javascript
js中单引号与双引号冲突问题解决方法
Oct 04 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
Aug 27 Javascript
jquery动态改变div宽度和高度
Feb 09 Javascript
悬浮广告方法日常收集整理
Mar 18 Javascript
基于jQuery实现页面搜索功能
Mar 26 Javascript
jquery横向纵向鼠标滚轮全屏切换
Feb 27 Javascript
Vue项目history模式下微信分享爬坑总结
Mar 29 Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
Apr 22 Javascript
Vue源码分析之Vue实例初始化详解
Aug 25 Javascript
JavaScript实现tab栏切换效果
Mar 16 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
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
《PHP编程最快明白》第八讲:php启发和小结
2010/11/01 PHP
yii通过小物件生成view的方法
2016/10/08 PHP
实例分析基于PHP微信网页获取用户信息
2017/11/24 PHP
php更新cookie内容的详细方法
2019/09/30 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
2019/12/31 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
动态改变textbox的宽高的js
2006/10/26 Javascript
jQuery contains过滤器实现精确匹配使用方法
2013/04/12 Javascript
jQuery焦点图切换特效插件封装实例
2013/08/18 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
JavaScript中return用法示例
2016/11/29 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
实战node静态文件服务器的示例代码
2018/03/08 Javascript
webpack实践之DLLPlugin 和 DLLReferencePlugin的使用教程
2019/06/10 Javascript
vue router 跳转时打开新页面的示例方法
2019/07/28 Javascript
node 标准输入流和输出流代码实例
2019/09/19 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
深入webpack打包原理及loader和plugin的实现
2020/05/06 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
2020/05/11 Javascript
js实现html滑动图片拼图验证
2020/06/24 Javascript
axios解决高并发的方法:axios.all()与axios.spread()的操作
2020/11/09 Javascript
[58:58]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第二场
2018/04/05 DOTA
[03:00]2018完美盛典_最佳英雄奖
2018/12/17 DOTA
python中WSGI是什么,Python应用WSGI详解
2017/11/24 Python
Python 脚本获取ES 存储容量的实例
2018/12/27 Python
Python3爬楼梯算法示例
2019/03/04 Python
使用Django搭建web服务器的例子(最最正确的方式)
2019/08/29 Python
html5 canvas绘制网络字体的常用方法
2019/08/26 HTML / CSS
全球性的奢侈品梦工厂:Forzieri(福喜利)
2019/02/20 全球购物
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
个人自荐书
2013/12/20 职场文书
优秀共产党员先进事迹材料
2014/05/06 职场文书
珍惜时间演讲稿
2014/05/14 职场文书
医院办公室主任岗位职责
2015/04/01 职场文书
2015年度企业工作总结
2015/05/21 职场文书