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 相关文章推荐
常用js字符串判断方法整理
Oct 18 Javascript
js中prototype用法详细介绍
Nov 14 Javascript
js数组操作常用方法
May 08 Javascript
JavaScript检测并限制复选框选中个数的方法
Aug 12 Javascript
JavaScript利用HTML DOM进行文档操作的方法
Mar 28 Javascript
Angular实现搜索框及价格上下限功能
Jan 19 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
Nov 13 Javascript
JS实现长图上下滚动效果
Mar 19 Javascript
webpack+express实现文件精确缓存的示例代码
Jun 11 Javascript
Js数组扁平化实现方法代码总汇
Nov 11 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
ECharts transform数据转换和dataZoom在项目中使用
Dec 24 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
实现了一个PHP5的getter/setter基类的代码
2007/02/25 PHP
PHP递归删除目录几个代码实例
2014/04/21 PHP
php将字符串转化成date存入数据库的两种方式
2014/04/28 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
微信公众平台开发教程④ ThinkPHP框架下微信支付功能图文详解
2019/04/10 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
Aster vs KG BO3 第三场2.18
2021/03/10 DOTA
Jquery实现图片左右自动滚动示例
2013/09/25 Javascript
JS小功能(setInterval实现图片效果显示时间)实例代码
2013/11/28 Javascript
JavaScript让网页出现渐隐渐显背景颜色的方法
2015/04/21 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
2016/09/05 Javascript
jquery精度计算代码 jquery指定精确小数位
2017/02/06 Javascript
js中变量的连续赋值(实例讲解)
2017/07/08 Javascript
如何在JavaScript中等分数组的实现
2020/12/13 Javascript
[47:03]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第二场 12.10
2020/12/13 DOTA
[47:03]完美世界DOTA2联赛PWL S3 access vs LBZS 第一场 12.20
2020/12/23 DOTA
Python中的魔法方法深入理解
2014/07/09 Python
python利用matplotlib库绘制饼图的方法示例
2016/12/18 Python
Python3 列表,数组,矩阵的相互转换的方法示例
2019/08/05 Python
Python如何使用bokeh包和geojson数据绘制地图
2020/03/21 Python
Django-migrate报错问题解决方案
2020/04/21 Python
深入了解Python 方法之类方法 &amp; 静态方法
2020/08/17 Python
Python自动化办公Excel模块openpyxl原理及用法解析
2020/11/05 Python
介绍java中初始化块的使用
2012/09/11 面试题
网络技术支持面试题
2013/04/22 面试题
应届生财务管理求职信
2013/11/06 职场文书
运动会广播稿100字
2014/01/11 职场文书
京剧自荐信
2014/01/26 职场文书
幼儿园安全检查制度
2014/01/30 职场文书
最美家庭活动方案
2014/08/31 职场文书
学习退步检讨书
2014/09/28 职场文书
自查自纠工作总结
2014/10/15 职场文书
2014全年工作总结
2014/11/27 职场文书
2015年元宵节活动总结
2015/02/06 职场文书
高校自主招生教师推荐信
2015/03/23 职场文书
幼儿园大班开学寄语(2016秋季)
2015/12/03 职场文书