App下載

jquery源碼探索之----事件系統(tǒng)Events

猿友 2020-12-31 16:17:45 瀏覽數(shù) (2672)
反饋

學(xué)習(xí) jquery 的深入,發(fā)現(xiàn) jquery 內(nèi)部確切之優(yōu)美,之前從沒覺得 jquery 是做網(wǎng)站必須的,但是現(xiàn)在看來,想做一個漏洞很少的網(wǎng)頁, jquery 是一個利器。

最近看 jquery 源碼看了很多,主要是看了一些底層支持模塊,也大概知道 jquery 內(nèi)部的原理是什么了,雖然記不到可能記不到很多 API,但是那不重要,看到官網(wǎng)的 API,閉著眼睛也知道它是干什么的了。

今天就來講說我認(rèn)為 jquery 內(nèi)部最復(fù)雜的模塊之一,事件系統(tǒng)。這個模塊一篇兩篇應(yīng)當(dāng)是講不完的了,那就一步一步跟我來梳理吧!

還是像平常一樣,上個圖先:

微信截圖_20201231141743

視察者模式之前就說過了吧,jquery 事件系統(tǒng)也是利用了視察者模式,在介紹之前,我們先來看看什么是 jquery 的數(shù)據(jù)緩存系統(tǒng)。

為何要使用 jquery 的事件系統(tǒng)?

(1)jquery 數(shù)據(jù)緩存系統(tǒng)

有些時候,我們需要給 js 對象或 DOM 對象附加一些數(shù)據(jù),為 js 對象附加數(shù)據(jù)就不說了,直接可以 object.data={},但是要給 DOM 元素附加數(shù)據(jù)時就要注意了。比以下面這類情況:

$(document).ready(function() { 
var button = document.getElementById('button⑴'); 
button.onclick = function() { 
console.log('hello'); return false; 
}; 
});

上面這類情勢的寫法相信大家是常常這樣寫的,我之前也是的,但是這類有什么壞處么,在非IE閱讀器中是沒什么問題,但是在古老的IE 瀏覽器中寫上上面這句話,問題就來了:

IE 的 dom 元素的垃圾回收機制是援用計數(shù)的方式,至于援用計數(shù)是什么方式,大家可以百度一下,這要是再展開,那就要說很久很久了。循環(huán)援用就出現(xiàn)了,只要循環(huán)援用一出現(xiàn),就會造成內(nèi)存泄漏。這里是怎樣造成循環(huán)援用的呢?

微信截圖_20201231142023

很明顯的看到,在閉包環(huán)境內(nèi),造成了循環(huán)援用,那怎樣樣來解決這個問題呢?那肯定就是數(shù)據(jù)緩存系統(tǒng)了。

怎樣樣避免這類循環(huán)情況?我們只需要破壞一條援用指針就能夠了。那究竟是破壞哪一條呢?

function 作用域鏈援用外面 button 這條指針明顯是不好破壞的,由于這里常常是開發(fā)者最容易寫的,那就破壞 button.click 指向匿名函數(shù)這條了。

那怎樣破壞這條路徑呢?

我們來看看 jquery 的事件緩存系統(tǒng)是怎樣做的:

微信截圖_20201231142103

在 jquery 當(dāng)中,并沒有直接援用對象,而是給 dom 元素設(shè)置了一個屬性 jquery12123213為1,1 為基本數(shù)據(jù)類型,所以不存在循環(huán)援用,但是這個1卻能跟 $.cache 當(dāng)中的屬性1相對應(yīng),那么根據(jù)這個一就可以找到對應(yīng)的事件處理函數(shù) fn,是否是覺得很奇妙,我也是這么認(rèn)為的。


0 人點贊