javascript – 为什么jQuery的.data方法表现得像这样? (可能的错误?)

发布时间:2019-04-24 发布网站:脚本之家
脚本之家收集整理的这篇文章主要介绍了javascript – 为什么jQuery的.data方法表现得像这样? (可能的错误?)脚本之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这段代码最能说明我的困惑.
var nativeObj,jWrapped,jSelector;

//WIAT = "What I Am Thinking"
nativeObj = $( '#tableTab' ) [0];  //WIAT: unwrap the jQuery object created by the selector and get the native DOM object
jWrapped = $( nativeObj );  //WIAT: wrap up the native DOM object again... should be equal to $( '#tableTab' )
jSelector = $( '#tableTab' );   //WIAT: pass the jQuery object as reference to jSelector variable

// set the data with jQuery's .data method
$.data( jWrapped,'key',{ test: 12 } );    //WIAT: will be equivalant to using $( '#tableTab' ) and should attach the data to it
$.data( $( '#tableTab' ) [0],{ test: 34 } );    //WIAT: using the native DOM obj,it shouldn't work with this,since it doesn't specify in the docs
$.data( $( '#tableTab' ),{ test: 56 } );   //WIAT: should rewrite the data in the element to { key: { test: 56} }

console.log( $.data ( jWrapped ) ); // {key:{test:12}}
console.log( $.data ( jWrapped[0] ) );  // {key:{test:34}}
console.log( $.data ( nativeObj ) );    // {key:{test:34}}
console.log( $.data ( $( nativeObj ),'test' ) );  // undefined  
console.log( $.data ( $( '#tableTab' ) [0] ) );  // {key:{test:34}}
console.log( $.data ( $( '#tableTab' ),'test' ) ); // undefined

哇,等等,发生什么事了?

1.为什么我得到不同的结果?我只使用了1个选择器并引用了一个元素.

2.为什么不是jWrapped的对象引用和$(‘#tableTab’)的对象产生相同的结果?

3.此外,jwrapped和jWrapped [0]产生了不同的结果?前者是jQuery包装对象,后者是本机DOM对象.基本上他们引用相同的元素与不同的结果!??

//Now let's see what's inside the objects
console.log( $( '#tableTab' ) [0]);  // [object HTMLDivElement]         
console.log( nativeObj );  // [object HTMLDivElement]
console.log( $( nativeObj ) );  // {0:({}),context:({}),length:1}
console.log( jWrapped );   // {0:({}),length:1,jQuery182021025872972076787:{toJSON:(function () {}),data:{key:{test:12}}}}
console.log( $( '#tableTab' ) );    // {length:1,0:({}),selector:"#tableTab"}
console.log( jSelector );   // {length:1,selector:"#tableTab"}

好nativeObj == $(‘#tableTab’)[0]这就是我的预期

哇,这很奇怪,为什么不jWrapped == $(nativeObj)?

好,jSelector = $(‘#tableTab’)这也是我的预期

鉴于这些数据,我推断$.data必须接受本机DOM元素

$( '#tableTab' ).data( 'key',{ test: 78 } );
console.log($( '#tableTab' ).data('key')); // 78

嗯,请原谅我的控制台…不是很酷的男人.

好吧我非常困惑和沮丧,我讨厌jQuery,我讨厌Javascript,我讨厌IE …
好吧,我只是讨厌IE,但这是另一个故事.为什么jQuery表现得那么奇怪?和IE一起玩的太多了我觉得……

我的猜测是它与$.data在jQuery中的工作方式有关,并且它实际上并没有将数据附加到元素,而是
将数据存储在自己的对象中,并基于解析传递的数据来引用数据.我找到了一个bug吗?

救命.

我也确实看过How does jQuery .data() work?,虽然确实提供了一些很好的信息,但它仍然没有回答这里发生的事情,这是我真正的问题.虽然它确实证实了我的想法,即没有数据存储在元素中,而是存储在jQuery对象中.

解决方法

查看chrome开发人员工具中的源代码,我在版本1.9( GitHub source here,函数internalData中的第17行)的第1564行找到了这条评论
// Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically

所以,这里发生的是,当你传入nativeObj时,它会将数据存储在$.cache中,但是否则它会将值存储到你传入的jQuery对象中.

看看这个小提琴:
http://jsfiddle.net/tomprogramming/SNqwh/

我对你原来的例子做了一些修改.首先是我传入你在顶部设置的对象.第二个是你在对象中查询一个名为“test”的数据,但是那里不存在 – 你正在存储一个碰巧有一个名为test的属性的对象 – 在“key”的属性下.

在日志语句的末尾,我添加了自己的,使用$.data的面向对象特性.每一次,我都得到相同的结果.我的猜测是它使用每个jQuery对象的底层dom节点来访问全局缓存,在你的情况下,它具有值{test:34}.

我确实认为这是意外的行为,因为新手用户看起来你选择了相同的元素,但我相信这只是$.data和$(selector).data()之间差异的下划线.后者总是使用底层的dom节点(因此总是’正确’),而前者将使用你传入的jQuery对象(如果可用).

编辑:this fiddle再次强调了差异.我使用$(selector).data()设置值,然后使用$.data再次将其拉出.用于原始对象的“缓存”没有改变(作为对象本身),但是对于底层DOM节点,全局缓存具有.

这里的课程:始终使用DOM节点或$().data.这是“最一致的”

总结

以上是脚本之家为你收集整理的javascript – 为什么jQuery的.data方法表现得像这样? (可能的错误?)全部内容,希望文章能够帮你解决javascript – 为什么jQuery的.data方法表现得像这样? (可能的错误?)所遇到的程序开发问题。

如果觉得脚本之家网站内容还不错,欢迎将脚本之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:76874919,请注明来意。
标签: