jQuery.data 分析

jquery data 相关方法

jquery@0.11.2, installed by bower

\$.fn.data(key,val)

  1. no argument , 获取所有 data

    1. 调用 \$.data
    2. 如果是第一次调用的时候,内部 data parsedAttr 为 false,这个时候遍历元素的 data-xxx attribute , 之后会设置到 全局的 cache,再次读取的时候不会再解析 attribute
  2. 1 argument , 根据 key 获取 data

    1. 调用\$.data -> internalData 就是取 各种 cache
    2. 1 中的结果为 undefined 的话,使用 dataAttr 方法,去读取 node 的 attribute
  3. 2 argument , 设置 key = val
    通过 internalData 设置

\$.cache

那么这些 data 设置在哪里呢?

  • 对一个 dom 节点进行 data 操作,存放在全局 \$.cache 中
  • 对一个普通的 js object 操作,存放在它自己中

jQuery 中有一段注释,解释为什么这么干

// We have to handle DOM nodes and JS objects differently because IE6-7
// can’t GC object references properly across the DOM-JS boundary

也就是 ie6-7 的 GC 问题

cache 也就是 data 操作的注册表 =

  • 对于 dom element, cache = $.cache[elem[$.expando]]
    elem.jQueryxxxx 维护着 一个 id , 表示在 \$.cache 中的索引
  • 对于 obj, cache = obj[$.expando]
    obj.jQueryxxxx 就是 这个 cache

关于 \$.expando , 是利用版本号,时间戳生成的常量,例如现在为 jQuery111206431590784341097

所以假设页面有个 id=test 的 element

1
$(test).data() === $.cache[test[$.expando]].data; // true

private or public

有 internal only data,例如上面说的获取 attribute 的时候,会生成 parsedAttrs = true 表示已经读取过该节点的 data attribute 了.

上面说了 cache , cache 的结构是

1
2
3
4
5
6
7
cache = {
data: {
// public data here
},
// here is private data , for jQuery internal use only
parsedAttrs: true
};

$.data() / $._data() 的区别就在这里 , 带 _ 的就是 internal only’s private data.

Em …

之前做 chrome 插件的时候,等待页面加载 jQuery,后面知道是插件的 script 是 sandbox 的,要用 jQ 得引用自己的,当时疑惑为什么页面上的 data,我在插件里就是取不到,其实是在 jQuery.cache 里面,我们的 script 不能访问页面上 jq 的 cache.

EOF