jQuery的实现原理的模拟代码 -2 数据部分


Posted in Javascript onAugust 01, 2010

这个数据当然要通过属性来进行存取,但是,有多个属性怎么办呢?,要定义多个属性吗?,属性的名字叫什么呢?会不会与其他的属性有冲突呢?
在 jQuery 中,针对 DOM 对象扩展的私有数据可以用一个对象来表示,多个数据就使用这个对象的多个属性来表示。为了能够通过 DOM 对象找到这个扩展数据对象,而不会与其他现有的属性冲突,在 jQuery 中通过 expando 这个常量表示扩展对象的属性名,这个 expando 的值是计算出来的。而这个属性的值就是用来找到扩展对象的键值。
例如,我们可以定义 expando 的值为 "jQuery1234" ,那么,我们可以为每个 DOM 对象增加这个名为 "jQuery1234" 的属性,这个属性的值可以是一个键,例如为 1000。
在 jQuery 对象上的 cache 用来保存所有对象扩展的对象,这个对象可以看作一个字典,属性名就是键值,所对应的值就是扩展数据对象。
也就是说,在 jQuery 对象的 cache 上,将会有一个 1000 的成员,这个成员引用的对象就是 1000 号 DOM 对象的私有扩展对象。1000 号成员的私有数据将被存在在这个对象上。
当一个 DOM 对象需要取得扩展数据的时候,首先通过对象的 expando 属性取得一个键值,然后通过这个键值到 jQuery.cache 中取得自己的扩展对象,然后在扩展对象上读写数据。

/// <reference path="jQuery-core.js" /> 
// 常用方法 
function now() { 
return (new Date).getTime(); 
} 
// 扩充数据的属性名,动态生成,避免与已有的属性冲突 
var expando = "jQuery" + now(), uuid = 0, windowData = {}; 
jQuery.cache = {}; 
jQuery.expando = expando; 
// 数据管理,可以针对 DOM 对象保存私有的数据,可以读取保存的数据 
jQuery.fn.data = function (key, value) { 
// 读取 
if (value === undefined) { 
return jQuery.data(this[0], key); 
} 
else { // 设置 
this.each( 
function () { 
jQuery.data(this, key, value); 
} 
); 
} 
} 
// 移除数据,删除保存在对象上的数据 
jQuery.fn.removeData = function (key) { 
return this.each(function () { 
jQuery.removeData(this, key); 
}) 
} // 为元素保存数据 
jQuery.data = function (elem, name, data) { // #1001 
// 取得元素保存数据的键值 
var id = elem[expando], cache = jQuery.cache, thisCache; 
// 没有 id 的情况下,无法取值 
if (!id && typeof name === "string" && data === undefined) { 
return null; 
} 
// Compute a unique ID for the element 
// 为元素计算一个唯一的键值 
if (!id) { 
id = ++uuid; 
} 
// 如果没有保存过 
if (!cache[id]) { 
elem[expando] = id; // 在元素上保存键值 
cache[id] = {}; // 在 cache 上创建一个对象保存元素对应的值 
} 
// 取得此元素的数据对象 
thisCache = cache[id]; 
// Prevent overriding the named cache with undefined values 
// 保存值 
if (data !== undefined) { 
thisCache[name] = data; 
} 
// 返回对应的值 
return typeof name === "string" ? thisCache[name] : thisCache; 
} 
// 删除保存的数据 
jQuery.removeData = function (elem, name) { // #1042 
var id = elem[expando], cache = jQuery.cache, thisCache = cache[id]; 
// If we want to remove a specific section of the element's data 
if (name) { 
if (thisCache) { 
// Remove the section of cache data 
delete thisCache[name]; 
// If we've removed all the data, remove the element's cache 
if (jQuery.isEmptyObject(thisCache)) { 
jQuery.removeData(elem); 
} 
} 
// Otherwise, we want to remove all of the element's data 
} else { 
delete elem[jQuery.expando]; 
// Completely remove the data cache 
delete cache[id]; 
} 
} 
// 检查对象是否是空的 
jQuery.isEmptyObject = function (obj) { 
// 遍历元素的属性,只有要属性就返回假,否则返回真 
for (var name in obj) { 
return false; 
} 
return true; 
} 
// 检查是否是一个函数 
jQuery.isFunction = function (obj) { 
var s = toString.call(obj); 
return toString.call(obj) === "[object Function]"; 
}

下面的脚本可以保存或者读取对象的扩展数据。
// 数据操作 
$("#msg").data("name", "Hello, world."); 
alert($("#msg").data("name")); 
$("#msg").removeData("name"); 
alert($("#msg").data("name"));
Javascript 相关文章推荐
IE和Firefox在JavaScript应用中的兼容性探讨
Apr 01 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
Aug 28 Javascript
JavaScript 学习历程和心得分享
Dec 12 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
Mar 02 Javascript
JavaScript基本语法讲解
Jun 03 Javascript
JavaScript实现数组随机排序的方法
Jun 26 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
May 17 Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
Apr 22 Javascript
Angular.js中angular-ui-router的简单实践
Jul 18 Javascript
纯js代码生成可搜索选择下拉列表的实例
Jan 11 Javascript
基于node搭建服务器,写接口,调接口,跨域的实例
May 13 Javascript
解决在Vue中使用axios用form表单出现的问题
Oct 30 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
Aug 01 #Javascript
jQuery validate 中文API 附validate.js中文api手册
Jul 31 #Javascript
jQuery对象[0]是什么含义?
Jul 31 #Javascript
动态调用CSS文件的JS代码
Jul 29 #Javascript
date.parse在IE和FF中的区别
Jul 29 #Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
Jul 29 #Javascript
jquery中对表单的基本操作代码
Jul 29 #Javascript
You might like
JavaScript表单常用验证集合
2008/01/16 Javascript
让JavaScript 轻松支持函数重载 (Part 1 - 设计)
2009/08/04 Javascript
javascript function调用时的参数检测常用办法
2010/02/26 Javascript
jquery 延迟执行实例介绍
2013/08/20 Javascript
juery框架写的弹窗效果适合新手
2013/11/27 Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
js对文章内容进行分页示例代码
2014/03/05 Javascript
javascript实现的一个随机点名功能
2014/08/26 Javascript
node.js中的console.log方法使用说明
2014/12/09 Javascript
js计算文本框输入的字符数
2015/10/23 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
Angularjs中如何使用filterFilter函数过滤
2016/02/06 Javascript
复杂的javascript窗口分帧解析
2016/02/19 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
webpack进阶——缓存与独立打包的用法
2017/08/02 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
Less 安装及基本用法
2018/05/05 Javascript
详解如何用typescript开发koa2的二三事
2018/11/13 Javascript
jQuery/JS监听input输入框值变化实例
2019/10/17 jQuery
vue el-table实现自定义表头
2019/12/11 Javascript
Python实现的文本编辑器功能示例
2017/06/30 Python
浅谈配置OpenCV3 + Python3的简易方法(macOS)
2018/04/02 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
在Python中pandas.DataFrame重置索引名称的实例
2018/11/06 Python
python tkinter库实现气泡屏保和锁屏
2019/07/29 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
学会迭代器设计模式,帮你大幅提升python性能
2021/01/03 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
如何在Canvas上的图形/图像绑定事件监听的实现
2020/09/16 HTML / CSS
澳大利亚婴儿喂养品牌:Cherub Baby
2018/11/01 全球购物
食堂员工工作职责
2013/12/18 职场文书
应届毕业生自荐信例文
2014/02/26 职场文书
辞职信模板(中英文版)
2015/02/27 职场文书
员工升职自荐信
2015/03/27 职场文书
爱国教育主题班会
2015/08/14 职场文书
《秦兵马俑》教学反思
2016/02/24 职场文书