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 相关文章推荐
DWR实现模拟Google搜索效果实现原理及代码
Jan 30 Javascript
js实现创建删除html元素小结
Sep 30 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
May 17 Javascript
javascript获取网页各种高宽及位置的方法总结
Jul 27 Javascript
Javascript 6里的4个新语法
Aug 25 Javascript
Node.js发送HTTP客户端请求并显示响应结果的方法示例
Apr 12 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
Jun 15 Javascript
vue-cli 如何打包上线的方法示例
May 08 Javascript
微信小程序实现文字跑马灯
May 26 Javascript
微信小程序new Date()方法失效问题解决方法
Jul 29 Javascript
Element的el-tree控件后台数据结构的生成以及方法的抽取
Mar 05 Javascript
加速vue组件渲染之性能优化
Apr 09 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
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
php中的PHP_EOL换行符详细解析
2013/10/26 PHP
Laravel框架路由配置总结、设置技巧大全
2014/09/03 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
PHP多进程之pcntl_fork的实例详解
2017/10/15 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
javascript 简练的几个函数
2009/08/29 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
nodejs 的 session 简单使用
2016/06/06 NodeJs
Javascript的动态增加类的实现方法
2016/10/20 Javascript
关于JavaScript中的this指向问题总结篇
2017/07/23 Javascript
JS简单实现父子窗口传值功能示例【未使用iframe框架】
2017/09/20 Javascript
Nodejs中crypto模块的安全知识讲解
2018/01/03 NodeJs
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
2018/04/20 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
Vue内部渲染视图的方法
2019/09/02 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
Python发送邮件功能示例【使用QQ邮箱】
2018/12/04 Python
python字符串循环左移
2019/03/08 Python
Matplotlib scatter绘制散点图的方法实现
2020/01/02 Python
python实现人机五子棋
2020/03/25 Python
Python限制内存和CPU使用量的方法(Unix系统适用)
2020/08/04 Python
Python实现Canny及Hough算法代码实例解析
2020/08/06 Python
python 利用jieba.analyse进行 关键词提取
2020/12/17 Python
互动出版网:专业书籍
2017/03/21 全球购物
Booking.com美国:全球酒店预订网站
2017/04/18 全球购物
英国内衣连锁店:Boux Avenue
2018/01/24 全球购物
印度和世界各地的精美产品:Ikka Dukka
2018/02/12 全球购物
面向中国市场的在线海淘美妆零售网站:Beauty House美丽屋
2021/03/02 全球购物
药学专业大学生个人的自我评价
2013/11/04 职场文书
公司年会抽奖活动主持词
2014/03/31 职场文书
工程承包协议书
2014/04/22 职场文书
学习退步检讨书
2014/09/28 职场文书
2014年技术员工作总结
2014/11/18 职场文书