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