今天 謝亮 兄弟和我討論一個東西的時候,談到了性能,他用的是 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 賦予我們的一把瑞士軍刀,非常鋒利的。
好了,我是懶人,懶的配圖,已經寫了不少字了,如果有什麼說的不對的地方,你們來打我吧