对 jQuery 中 data 方法的误解分析
今天谢亮兄弟和我讨论一个东西的时候,谈到了性能,他用的是attr操作自定义属性data-uid,我说用data好,因为是dataset实现,然后他去翻了下jQuery源码和我说,没有发现这个东西,我就纳闷了。于是我去仔细读了下data方法的源码,才发现我一直误会了,再此,向之前问我data方法的群友道歉,我"骗"了你们,你们来打我吧。
今天我就重新解释下data方法,先看下jQuery1.11.0的手册里肿么说的吧,请移步至http://shouce.jb51.net/jquery/data.html、
用法这里说的很清楚了,但是内部是怎么实现的呢?戳我看源码 (看不懂没关系,我会简单分析下他的流程)
其实是这样的,当我们执行例如这样的语句时$("#id").data("test");(简化后的过程) 第一步:jQuery会获取到$("#id")元素,对吧、 第二步:执行到data方法的时候,他会通过attributes取我们要的对应值。 第三步:返回结果给我们,然后jQuery把值缓存到内部对象里 第一次取的时候,我们可以得到的undefined,字符串,数字或者解析后的json。 那有人会说这个和attr有什么区别呢? 当我们第二次执行$("#id").data("test");的时候: 第一步:jQuery会获取到$("#id")元素,和上面一样。 第二步:执行到data方法的时候,从jQuery的缓存中取值 第三步:返回结果给我们 发现第二步不同了,对吧,为什么不是从attributes取值,而是从缓存中取呢? 缓存其实是js的对象,简单说就类似varcache={};jQuery在第一次取值之后就会保存到这个缓存对象中,这样我们再次操作的时候就非常快了、 往往性能的损耗都是在dom操作上,所以避免重复操作dom是非常必要的。 到这,也能看出他和attr最大的区别了,比如<divid="id"data-test="hehe"></div> $("#id").data("test","123");执行后依然是data-test="hehe" $("#id").attr("data-test","123");执行后会是data-test="123" 那么我们要给一个元素赋值值,或者对象的时候他们有什么区别呢?比如<divid="id"data-test="hehe"></div> $("#id").data("test",{str:"hehe"});会把{str:"hehe"}赋值给缓存,元素节点上依然是data-test="hehe" $("#id").attr("data-test",{str:"hehe"});执行后会是data-test="[objectObject]" 这个应该也有不少人遇到,至少群里有不少人问过这个问题。
其实我之前也没骗你们,自定义属性没必要老是attr他,data是jQuery赋予我们的一把瑞士军刀,非常锋利的。
好了,我是懒人,懒的配图,已经写了不少字了,如果有什么说的不对的地方,你们来打我吧