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 while语句和do while语句的区别分析
Dec 08 Javascript
jQuery 页面 Mask实现代码
Jan 09 Javascript
Javascript类定义语法,私有成员、受保护成员、静态成员等介绍
Dec 08 Javascript
JS文本获得焦点清除文本文字的示例代码
Jan 13 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
Aug 12 Javascript
易被忽视的js事件问题总结
May 14 Javascript
Bootstrap教程JS插件滚动监听学习笔记分享
May 18 Javascript
基于JavaScript实现的折半查找算法示例
Apr 14 Javascript
JS实现AES加密并与PHP互通的方法分析
Apr 19 Javascript
Vue项目数据动态过滤实践及实现思路
Sep 11 Javascript
JS实现查找数组中对象的属性值是否存在示例
May 24 Javascript
小程序的上传文件接口的注意要点解析
Sep 17 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
Linux下ZendOptimizer的安装与配置方法
2007/04/12 PHP
PHP设计模式之装饰者模式代码实例
2015/05/11 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
PHP验证码类ValidateCode解析
2017/01/07 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
图片自动缩小 点击放大
2008/07/07 Javascript
js登录弹出层特效
2014/03/07 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
浅谈Javascript中深复制
2014/12/01 Javascript
原生JS和JQuery动态添加、删除表格行的方法
2015/05/28 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
jQuery简单实现页面元素置顶时悬浮效果示例
2016/08/01 Javascript
JS中Select下拉列表类(支持输入模糊查询)功能
2017/01/17 Javascript
用原生js做单页应用
2017/01/17 Javascript
利用Jasmine对Angular进行单元测试的方法详解
2017/06/12 Javascript
详解webpack2异步加载套路
2018/09/14 Javascript
webpack 从指定入口文件中提取公共文件的方法
2018/11/13 Javascript
Vue2.x Todo之自定义指令实现自动聚焦的方法
2019/01/08 Javascript
node实现爬虫的几种简易方式
2019/08/22 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
python3大文件解压和基本操作
2017/12/15 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
多个应用共存的Django配置方法
2018/05/30 Python
python 字典操作提取key,value的方法
2019/06/26 Python
使用python实现滑动验证码功能
2019/08/05 Python
Django 简单实现分页与搜索功能的示例代码
2019/11/07 Python
python 求定积分和不定积分示例
2019/11/20 Python
使用Python串口实时显示数据并绘图的例子
2019/12/26 Python
有机婴儿毛毯和衣服:Monica + Andy
2020/03/01 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
个人求职信范文分享
2013/12/13 职场文书
卖房协议书
2014/04/11 职场文书
党性心得体会
2014/09/03 职场文书
小学生教师节演讲稿
2014/09/03 职场文书
CSS完成视差滚动效果
2021/04/27 HTML / CSS