深入理解jQuery.data() 的實作方式
jQuery.data() 的作用是為普通物件或 DOM Element 附加(及取得)資料。
下面將分三個部分分析其實現方式:
1. 用name和value為對象附加資料;即傳入三個參數,第一個參數為需要附加資料的對象,第二個參數為資料的名稱,第三個參數為資料的值。當然,只是取得值的話,也可以不傳入第三個參數。
2. 用另一個物件為物件附加資料;即傳入兩個參數,第一個參數為需要附加的資料物件(我們稱之為「obj」),第二個參數也是物件(我們稱為「another」);「another」中包含的鍵值對將會被複製到「obj」 的資料快取(我們稱之為「cache」)。
3. 為DOM Element 附加資料;DOM Element 也是一種Object ,但IE6、IE7 對直接附加在DOM Element 上的物件的垃圾回收存在問題;因此我們將這些資料存放在全域快取(我們稱之為為“globalCache”)中,即“globalCache” 包含了多個DOM Element 的“cache”,並在DOM Element 上添加一個屬性,存放“cache” 對應的uid 。
用name和value為物件附加資料
使用 jQuery.data() 為普通物件附加資料時,其本質是將一個 “cache” 附加到了物件上,並使用了一個特殊的屬性名稱。
存放資料的 “cache” 也是 object,我們為 “obj” 附加的資料其實成為了 “cache” 的屬性。而 “cache” 又是 “obj” 的屬性,在 jQuery 1.6中,這個屬性的名稱是 “jQuery16”加上一個隨機數(如下面提到的 “jQuery16018518865841457738” )。
我們可以用下面的程式碼來測試jQuery.data() 的功能:
<script type="text/javascript" src="jqueryjs"></script> <script> obj = {}; $data(obj, 'name', 'value'); documentwrite("$data(obj, 'name') = " + $data(obj, 'name') + '<br />'); for (var key in obj) { documentwrite("obj" + key + 'name = ' + obj[key]name); } </script>
顯示結果是:
$.data(obj, 'name') = value obj.jQuery16018518865841457738.name = value
顯示結果為:
obreee
了一個屬性(名稱為“name”,值為“value”),然後透過$.data(obj, 'name') 來取得所附加的資料。為了深入了解其中的實作機制,我們有使用了一個迴圈來取得 “obj” 的屬性,實際上是取出了在 “obj” 上附加的 “cache”物件。
可以看到,jQuery.data() 實際上為 “obj” 附加到了名為 “jQuery16018518865841457738” (這個名稱是隨機的)的對象,也就是 “cache” 上。用 jquery.data() 方式為物件附加的屬性其實成為了這個 “cache” 的屬性。
我們可以用下面的程式碼實現類似的功能:
$ = function() { var expando = "jQuery" + ("6" + Mathrandom())replace(/\D/g, ''); function getData(cache, name) { return cache[name]; } function setData(cache, name, value) { cache[name] = value; } function getCache(obj) { obj[expando] = obj[expando] || {}; return obj[expando]; } return { data : function(obj, name, value) { var cache = getCache(obj); if (value === undefined) { return getData(cache, name); } else { setData(cache, name, value); } } } }();
function 中的第一行程式碼定義了「expando」 ,即"jQuery1.6" 加上一個隨機數(0.xxxx),並將其中非數字的部分去掉;這種格式將在jQuery的其他地方用到,這裡不做探討;只需要知道這是一個特殊的名稱,並且可以用於標識不同的頁面(比如不同iframe 中的“expando” 就會有所不同)。
最後公開了data 方法,先根據傳入的“obj”,獲取附加在“obj” 上的“cache”; 當傳入兩個參數時,調用getData()方法;當傳入三個參數時,則呼叫setData() 方法。
用另一個物件為物件附加資料
除了以提供 name 和 value 的方式進行賦值,我們還可以直接傳入另一個物件( “another” )作為參數。在這種情況下,「another」 的屬性名稱和屬性值將被視為多個鍵值對,從中提取的 “name” 和 “value” 都會複製到目標物件的快取中。
功能測試程式碼如下:
<script type="text/javascript" src="jqueryjs"></script> <script> obj = {}; $data(obj, {name1: 'value1', name2: 'value2'}); documentwrite("$data(obj, 'name1') = " + $data(obj, 'name1') + '<br />' ); documentwrite("$data(obj, 'name2') = " + $data(obj, 'name2') + '<br />'); for (var key in obj) { documentwrite("obj" + key + 'name1 = ' + obj[key]name1 + '<br />'); documentwrite("obj" + key + 'name2 = ' + obj[key]name2); } </script>
顯示結果如下:
$.data(obj, 'name1') = value1 $.data(obj, 'name2') = value2 obj.jQuery1600233050178663064.name1 = value1 obj.jQuery1600233050178663064.name2 = value2
的測試碼中然後分別用$.data(obj, 'name1') 和$.data(obj, 'name2') 取得附加的資料;同樣,為了深入了解其中的機制,我們透過遍歷「obj」 的方式取出了隱藏的“cache” 對象,並獲得了“cache” 對象的“name1” 屬性和“name2” 屬性的值。
可以看到,jQuery.data() 實際上為 “obj” 附加了名為 “obj.jQuery1600233050178663064” 的對象,也就是 “cache” 上。用 jquery.data() 方式傳入的鍵值對都複製到了 “cache” 中。
我們可以用下面的程式碼實現類似的功能:
$ = function() { // Other codes function setDataWithObject(cache, another) { for (var name in another) { cache[name] = another[name]; } } // Other codes return { data : function(obj, name, value) { var cache = getCache(obj); if (name instanceof Object) { setDataWithObject(cache, name) } else if (value === undefined) { return getData(cache, name); } else { setData(cache, name, value); } } } }();
🎜🎜
这段代码是在之前的代码的基础上进行修改的。首先增加了内部函数 setDataWithObject() ,这个函数的实现是遍历 “another” 的属性,并复制到 “cache” 中。
然后,在对外开放的 data 函数中,先判断传入的第二个参数的名称,如果这个参数是一个 Object 类型的实例,则调用 setDataWithObject() 方法。
为 DOM Element 附加数据
由于 DOM Element 也是一种 Object,因此之前的方式也可以为 DOM Element 赋值;但考虑到 IE6、IE7 中垃圾回收的问题(不能有效回收 DOM Element 上附加的对象引用),jQuery采用了与普通对象有所不同的方式附加数据。
测试代码如下:
<div id="div_test" /> <script type="text/javascript" src="datajs"></script> <script> windowonload = function() { div = documentgetElementById('div_test'); $data(div, 'name', 'value'); documentwrite($data(div, 'name')); } </script>
显示结果如下:
value
测试代码中,首先通过 document.getElementById 方法获取了一个 DOM Element (当然,也可以用 jQuery 的选择器),然后在这个 DOM Element 上附加了一个属性,随后就从 DOM Element 上取出了附加的属性并输出。
因为考虑到 IE6、IE7 对 DOM Element 上的对象引用的垃圾回收存在问题,我们不会直接在 DOM Element 上附加对象;而是使用全局cache,并在 DOM Element 上附加一个 uid。
实现方式如下:
$ = function() { var expando = "jQuery" + ("6" + Mathrandom())replace(/\D/g, ''); var globalCache = {}; var uuid = 0; // Other codes function getCache(obj) { if (objnodeType) { var id = obj[expando] = obj[expando] || ++uuid; globalCache[id] = globalCache[id] || {}; return globalCache[id]; } else { obj[expando] = obj[expando] || {}; return obj[expando]; } } // Other codes }();
这段代码与之前的代码相比,增加了 globalCache 和 uuid,并修改了 getCache() 方法。
globalCache 对象用于存放附加到 DOM Element 上的 “cache”,可以视为 “cache” 的“容器”。uuid 表示 “cache” 对应的唯一标识,是唯一且自增长的。uuid 或被存放在 DOM Element 的 “expando” 属性中。
getCache() 函数中增加了一个判断,即 “obj” 具有 “nodeType” 属性,就认为这是一个 DOM Element;这种情况下,就先取出附加在 “obj” 上的 id ,即 obj[expando] ;如果 obj[expando] 未定义,则先用 ++uuid 对其进行初始化;取出 id 之后,就到 globalCache 中找到对应的 “cache” ,即 globalCache[id], 并返回。
到此为止,jQuery.data() 函数的实现就介绍完了;但是,这里还有一个需要思考的问题:为什不都统一用 “globalCache” 存储,而要将 “cache” 直接附加到普通对象上?我认为这应该是一种性能优化的方式,毕竟少一个引用的层次,存取速度应该会略快一些。 jQuery 中这刻意优化的地方非常多,在许多原本可以统一处理的对方都进行了特殊处理。但这在一定程度上,也造成了阅读源码的障碍。当然这是作者(及其他代码贡献者)本身的编程哲学,这里就不加评论了。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

jQuery引用方法詳解:快速上手指南jQuery是一個受歡迎的JavaScript庫,被廣泛用於網站開發中,它簡化了JavaScript編程,並為開發者提供了豐富的功能和特性。本文將詳細介紹jQuery的引用方法,並提供具體的程式碼範例,幫助讀者快速上手。引入jQuery首先,我們需要在HTML檔案中引入jQuery函式庫。可以透過CDN連結的方式引入,也可以下載

jQuery中如何使用PUT請求方式?在jQuery中,發送PUT請求的方法與發送其他類型的請求類似,但需要注意一些細節和參數設定。 PUT請求通常用於更新資源,例如更新資料庫中的資料或更新伺服器上的檔案。以下是在jQuery中使用PUT請求方式的具體程式碼範例。首先,確保引入了jQuery庫文件,然後可以透過以下方式發送PUT請求:$.ajax({u

jQuery是一款廣泛應用於前端開發的快速、小巧、功能豐富的JavaScript庫。自2006年發布以來,jQuery已成為眾多開發者的首選工具之一,但在實際應用中,它也不乏一些優點和缺點。本文將深度剖析jQuery的優勢與劣勢,並結合具體的程式碼範例進行說明。優點:1.簡潔的語法jQuery的語法設計簡潔明了,可以大幅提升程式碼的可讀性和編寫效率。比如,

標題:jQuery小技巧:快速修改頁面所有a標籤的文字在網頁開發中,我們經常需要對頁面中的元素進行修改和操作。使用jQuery時,有時候需要一次修改頁面中所有a標籤的文字內容,這樣可以節省時間和精力。以下將介紹如何使用jQuery快速修改頁面所有a標籤的文本,同時給出具體的程式碼範例。首先,我們需要引入jQuery庫文件,確保在頁面中引入了以下程式碼:<

jQuery如何移除元素的height屬性?在前端開發中,經常會遇到需要操作元素的高度屬性的需求。有時候,我們可能需要動態改變元素的高度,而有時候又需要移除元素的高度屬性。本文將介紹如何使用jQuery來移除元素的高度屬性,並提供具體的程式碼範例。在使用jQuery操作高度屬性之前,我們首先需要了解CSS中的height屬性。 height屬性用於設定元素的高度

標題:使用jQuery修改所有a標籤的文字內容jQuery是一款受歡迎的JavaScript庫,被廣泛用於處理DOM操作。在網頁開發中,經常會遇到需要修改頁面上連結標籤(a標籤)的文字內容的需求。本文將介紹如何使用jQuery來實現這個目標,並提供具體的程式碼範例。首先,我們需要在頁面中引入jQuery庫。在HTML檔案中加入以下程式碼:

jQuery是一種流行的JavaScript庫,被廣泛用於處理網頁中的DOM操作和事件處理。在jQuery中,eq()方法是用來選擇指定索引位置的元素的方法,具體使用方法和應用場景如下。在jQuery中,eq()方法選擇指定索引位置的元素。索引位置從0開始計數,即第一個元素的索引是0,第二個元素的索引是1,依此類推。 eq()方法的語法如下:$("s

如何判斷jQuery元素是否具有特定屬性?在使用jQuery操作DOM元素時,常會遇到需要判斷元素是否具有某個特定屬性的情況。在這種情況下,我們可以藉助jQuery提供的方法來輕鬆實現這項功能。以下將介紹兩種常用的方法來判斷一個jQuery元素是否具有特定屬性,並附上具體的程式碼範例。方法一:使用attr()方法和typeof運算子//判斷元素是否具有特定屬
