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 相关文章推荐
一个不错的应用,用于提交获取文章内容,不推荐用
Mar 03 Javascript
jquery简单实现外部链接用新窗口打开的方法
May 30 Javascript
javascript中对变量类型的判断方法
Aug 09 Javascript
jquery.serialize() 函数语法及简单实例
Jul 08 Javascript
jQuery 获取页面li数组并删除不在数组中的key
Aug 02 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
Jun 14 Javascript
Vue.js仿微信聊天窗口展示组件功能
Aug 11 Javascript
解决vue-cli创建项目的loader问题
Mar 13 Javascript
微信小程序控制台提示warning:Now you can provide attr &quot;wx:key&quot; for a &quot;wx:for&quot; to improve performance解决方法
Feb 21 Javascript
详解小程序如何避免多次点击,重复触发事件
Apr 08 Javascript
微信小程序 scroll-view 实现锚点跳转功能
Dec 12 Javascript
ES2020 已定稿,真实场景案例分析
May 25 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
一个可以找出源代码中所有中文的工具
2006/10/25 PHP
PHP命名空间用法实例分析
2019/09/04 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
js 发个判断字符串是否为符合标准的函数
2009/04/27 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
鼠标滑过出现预览的大图提示效果
2014/02/26 Javascript
Javascript实现获取窗口的大小和位置代码分享
2014/12/04 Javascript
JSON取值前判断
2014/12/23 Javascript
JS获取表格内指定单元格html内容的方法
2015/03/31 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
2016/11/11 Javascript
JavaScript canvas实现围绕旋转动画
2017/11/18 Javascript
详解vue-meta如何让你更优雅的管理头部标签
2018/01/18 Javascript
浅谈vue项目4rs vue-router上线后history模式遇到的坑
2018/09/27 Javascript
[02:16]DOTA2超级联赛专访Burning 逆袭需要抓住机会
2013/06/24 DOTA
Django admin美化插件suit使用示例
2017/12/12 Python
python nmap实现端口扫描器教程
2020/05/28 Python
Django 自动生成api接口文档教程
2019/11/19 Python
python flask中动态URL规则详解
2019/11/22 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
2020/04/24 Python
python 实现学生信息管理系统的示例
2020/11/28 Python
Python3.9.0 a1安装pygame出错解决全过程(小结)
2021/02/02 Python
BRASTY捷克:购买香水、化妆品、手袋和手表
2017/07/12 全球购物
网游商务专员求职信
2013/10/15 职场文书
保研推荐信
2014/05/09 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
机关党员公开承诺书
2014/08/30 职场文书
施工员岗位职责
2015/02/10 职场文书
学校计划生育责任书
2015/05/09 职场文书
2016继续教育研修日志
2015/11/13 职场文书
学校标语口号大全
2015/12/26 职场文书
《角的初步认识》教学反思
2016/02/17 职场文书
Python并发编程实例教程之线程的玩法
2021/06/20 Python
详细了解java监听器和过滤器
2021/07/09 Java/Android
python单向链表实例详解
2022/05/25 Python
hive数据仓库新增字段方法
2022/06/25 数据库