今天謝亮兄弟和我討論一個東西的時候,談到了性能,他用的是attr 操作自定義屬性data-uid,我說用data 好,因為是dataset 實現,然後他去翻了下jQuery源碼跟我說,沒有發現這個東西,我就納悶了。於是我去仔細讀了下 data 方法的源碼,才發現我一直誤會了,再此,向之前問我 data 方法的群友道歉,我 "騙" 了你們,你們來打我吧。
今天我就重新解釋下data 方法,先看下jQuery 1.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的对象,简单说就类似 var cache = {}; jQuery 在第一次取值之后就会保存到这个缓存对象中,这样我们再次操作的时候就非常快了、 往往性能的损耗都是在 dom 操作上,所以避免重复操作 dom 是非常必要的。 到这,也能看出他和 attr 最大的区别了,比如 <div id="id" data-test="hehe"></div> $("#id").data("test", "123"); 执行后依然是 data-test="hehe" $("#id").attr("data-test", "123"); 执行后会是 data-test="123" 那么我们要给一个元素赋值值,或者对象的时候他们有什么区别呢?比如 <div id="id" data-test="hehe"></div> $("#id").data("test", {str: "hehe"}); 会把 {str: "hehe"} 赋值给 缓存,元素节点上依然是 data-test="hehe" $("#id").attr("data-test", {str: "hehe"}); 执行后会是 data-test="[object Object]" 这个应该也有不少人遇到,至少群里有不少人问过这个问题。
其實我之前也沒騙你們,自訂屬性沒必要老是 attr 他,data 是 jQuery 賦予我們的一把瑞士軍刀,非常鋒利的。
好了,我是懶人,懶的配圖,已經寫了不少字了,如果有什麼說的不對的地方,你們來打我吧