jQ的数据管理【前篇】
发布在# 菜鸟解读 jQuery #2014年5月27日view:4005
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

愉快的51假日结束了,马上又开始了紧张的工作日,结束了之前的兼容,小编也为大家带来新的开始

本章向大家介绍 jQ的数据操作部分,本部分也分3篇,小编会在本周全部奉献
$.data(), $().data(),
$._data(),
$.removeData(), $().removeData();
先来介绍下各个api的使用情况

// 设置 key-val
$.data(divElement,'name','div');
$(divElement).data('name','div');

// 批量设置 key-val
$.data(divElement,{
    'name': 'div',
    'age': 19
});
$(divElement).data({
    'name': 'div',
    'age': 19
});

// 删除元素上的 name 属性
$.removeData(div,'name');
$(div).removeData('name');

// 获取 key 对应的 val
$.data(divElement,'name');
$(divElement).data('name');

// 获取元素所有的数据
$.data(divElement);
$(divElement).data();

$._data 是用来设置jQ内部使用的数据信息的,比如一些事件的数据

下面小编再来说明下jQ的实现过程
当你需要对元素绑定数据时,JQ会对元素设置一个标示, jQuery172016205299156717956:1
所有的元素对应的数据都会被设置到 $.cache 这个全局对象上,
通过自身属性上的jq标示对应的id值来进行索引性查找

数据分为两种类别:
用户自定义设置的的 $().data(), $.data()
jQ内部在一些功能上给元素绑定的一些数据【比如事件】$._data()

用户自定义的属性都是被保存到了 id对应对象的 data 属性中,
而系统内部使用的数据直接绑定到了元素id对应的对象中,
我们来看个例子,
比如我们的页面上有个div,然后添加一个数据: $(div).data('name','div')
然后我们来打印 $.cache 这个全局对象【结构如下】

$.cache = {
    1: {
        data:{
            name: 'div'
        }
    }
}

对照上面的说明我们在集合例子解释下:
如果我们去console.dir(div)去打印这个div详情的时候,会发现div身上有个jQ**属性,对应值是1
这个1就是 $.cache 上的1,在1对应的对象上出现了个data属性,这个属性对应的对象里面才是我们设定的数据 name:'div'
那么什么叫"jQ内部数据"呢?
比如此时我们对div添加了一个事件 $(div).on('click',fn);
再打印 $.cache 时,会发现:

1:{
    event:Object,
    data:Object,
    handle:function
}

我们发现div对应的数据缓存对象上出现了event对象和handle函数,这两个就是jQ系统添加上去的。

在jQ中,关于dom元素的数据,事件,运动,这些所逻辑中需要用到的数据都保存到了 $.cache 这个全局对象上,
通过元素上的jQ id来进行关联,
这么做可以避免js对象和dom元素之间出现循环引用,以及由此导致的内存泄露问题。

我们来看下关于这块的代码骨架:

jQuery.extend({
    //全局缓存对象
    cache: {},
    //标示id: 每遇到一个新的元素这个id就会执行 ++ ,
    //这个id就是上文中我们提到的jQ标示这个属性对应的数字id
    uuid: 0,
    // 为jQ制作一个唯一标示
    // 页面加载后执行,生成一个jQ标示符: "jQuery523432424342"
    expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),

    // 如果你尝试给以下元素添加扩展属性,将抛出“无法捕捉”的异常
    // 这里声明的几个元素对象是不给于数据绑定的
    noData: {
        "embed": true,
        // 除了flash的所有对象
        // 这个clsid是flash标示,小编暂时也不知道这是什么意思。
        "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
        "applet": true
    },
    // 检查对象是否已经相关联的数据
    hasData: function( elem ) {},
    //在使用外部api的时候则不会启用 data- 的检测
    data: function( elem, name, data, pvt ) {},
    //移除对象某个属性
    //这里其实很多变量表示和语句都类似于data()
    removeData: function( elem, name, pvt ) {},
    // 添加一个内部数据
    _data: function( elem, name, data ) {},
    // 检测一个属性是否可以绑定数据
    acceptData: function( elem ) {}
});
// 这是给jq元素操作进行的扩展
// 使用时是这样的: $().data(), $().removeData()
jQuery.fn.extend({
    data: function( key, value ) {},
    removeData: function( key ) {}
});

// 这里函数是用来解析elem元素身上的html5标签 "data-" 的值
// 如果传入的data对象有值的话,则直接返回不进行解析
function dataAttr( elem, key, data ) {}

// 检查obj是否是一个空的数据对象
// 这可不是检查是空对象,之前小编也解释过了,数据缓存对象和正常对象不同哈,
// 至少还有个特定意义的data属性
function isEmptyDataObject( obj ) {}

本篇就介绍到这里,多有言语不清之处,欢迎读者留言,小编也是新人,还请见谅

感谢您的阅读,欢迎留言:交流,提问,斧正

评论
发表评论
4年前

@前端狮子_北京 大概理解了,谢谢

4年前

@Junyue Cao 您好,在IE下,DOM对象和JS对象实例相互引用,就会造成内存泄漏,比如我们在一个div元素身上绑定一个自定义的属性,属性关联了一个对象,可能这个对象存放的会是你需要用到的一些关联数据,但这就造成了DOM引用了JS对象,而JQ的data操作,也可以给DOM关联任何数据参数,不过jQ的做法是用一个标示符去映射DOM和$.cache缓存的数据,避免了DOM元素直接使用属性去引用一个JS对象

4年前

问下,

在jQ中,关于dom元素的数据,事件,运动,这些所逻辑中需要用到的数据都保存到了 $.cache 这个全局对象上, 通过元素上的jQ id来进行关联,

这么做可以避免js对象和dom元素之间出现循环引用,以及由此导致的内存泄露问题。

这段该如何理解呢

WRITTEN BY
前端狮子
JS前端开发工程师 :喜欢研究js,nodejs,html5; 希望结交更多朋友~
TA的新浪微博
PUBLISHED IN
# 菜鸟解读 jQuery #

本栏解读的jQ为1.7.2版本。 本人也是刚开始读起源码,在这里分享下成长的心得。 本人能力有限,也是接触JS不久的初学者,定会有不少解析不全不够明朗【甚至BUG】的地方, 希望各位牛牛多多留言斧正 感谢阅读 ps:由于工作不定时繁忙,本人也无法定期更新,但是会尽量抽时间学习,分享给大家

我的收藏