鋒利的JQuery

因為我上一個系列的文章是關於有關WEB工程師的自學方面的,提到web工程師就不得不提到jquery,先了解一下什麼是jquery吧。

設計理念

jQuery 是一款革命性的 JavaScript 庫,秉承著「以用為本」的設計理念,倡導「寫更少的代碼,做更多的事」(write less, do more),極大地提升了 JavaScript 開發體驗。

jQuery 的核心特性可以總結為:

‰ 兼容主流瀏覽器 ,支持 IE 6.0+、Chrome、Firefox 3.6+、Safari 5.0+、Opera 等。1‰ 具有獨特的鏈式語法和短小清晰的多功能介面。

‰ 具有高效靈活的 CSS 選擇器,並且可對 CSS 選擇器進行擴展。‰ 擁有便捷的插件擴展機制和豐富的插件。

Advertisements


總體架構

jQuery 的模塊可以分為 3 部分:入口模塊、底層支持模塊和功能模塊,如圖 1-1 所示, 圖中還展示了模塊之間的主要依賴關係。

來看看圖 1-1 中各個模塊的功能和依賴關係。

在構造 jQuery 對象模塊中,如果在調用構造函數 jQuery() 創建 jQuery 對象時傳入了選 擇器表達式,則會調用選擇器 Sizzle 遍歷文檔,查找與之匹配的 DOM 元素,並創建一個包 含了這些 DOM 元素引用的 jQuery 對象。

選擇器 Sizzle 是一款純 JavaScript 實現的 CSS 選擇器引擎,用於查找與選擇器表達式匹 配的元素集合。

工具方法模塊提供了一些編程輔助方法,用於簡化對 jQuery 對象、DOM 元素、數組、 對象、字元串等的操作,例如,jQuery.each()、.each()、jQuery.map()、.map() 等,其他所有 的模塊都會用到工具方法模塊

Advertisements

瀏覽器功能測試模塊提供了針對不同瀏覽器功能和 bug 的測試結果,其他模塊則基於這 些測試結果來解決瀏覽器之間的兼容性問題。

在底層支持模塊中,回調函數列表模塊用於增強對回調函數的管理,支持添加、移除、 觸發、鎖定、禁用回調函數等功能;非同步隊列模塊用於解耦非同步任務和回調函數,它在回調 函數列表的基礎上為回調函數增加了狀態,並提供了多個回調函數列表,支持傳播任意同步 或非同步回調函數的成功或失敗狀態;數據緩存模塊用於為 DOM 元素和 JavaScript 對象附加 任意類型的數據;隊列模塊用於管理一組函數,支持函數的入隊和出隊操作,並確保函數按 順序執行,它基於數據緩存模塊實現。

在功能模塊中,事件系統提供了統一的事件綁定、響應、手動觸發和移除機制,它並沒 有將事件直接綁定到 DOM 元素上,而是基於數據緩存模塊來管理事件;Ajax 模塊允許從服 務器上載入數據,而不用刷新頁面,它基於非同步隊列模塊來管理和觸發回調函數;動畫模塊 用於向網頁中添加動畫效果,它基於隊列模塊來管理和執行動畫函數;屬性操作模塊用於對 HTML 屬性和 DOM 屬性進行讀取、設置和移除操作;DOM 遍歷模塊用於在 DOM 樹中遍歷 父元素、子元素和兄弟元素;DOM 操作模塊用於插入、移除、複製和替換 DOM 元素;樣式 操作模塊用於獲取計算樣式或設置內聯樣式;坐標模塊用於讀取或設置 DOM 元素的文檔坐 標;尺寸模塊用於獲取 DOM 元素的高度和寬度。

下面來看看 jQuery 源碼的總體結構,其中展示了各個模塊在源碼中的位置。

(function( window, undefined ) { // 構造 jQuery 對象

var jQuery = (function() {

var jQuery = function( selector, context ) {

return new jQuery.fn.init( selector, context, rootjQuery ); }

return jQuery; })();

// 工具方法 Utilities

// 回調函數列表 Callbacks Object

// 非同步隊列 Deferred Object

// 瀏覽器功能測試 Support

// 數據緩存 Data

// 隊列 Queue

// 屬性操作 Attributes

// 事件系統 Events

// 選擇器 Sizzle

//DOM 遍歷 Traversing

//DOM 操作 Manipulation

// 樣式操作 CSS(計算樣式、內聯樣式)

// 非同步請求 Ajax

// 動畫 Effects

// 坐標 Offset、尺寸 Dimensions window.jQuery = window.$ = jQuery;

})(window);


自調用匿名函數

jQuery 的所有代碼都被包裹在了一個立即執行的匿名函 數表達式中,這種代碼結構稱為「自調用匿名函數」。當瀏覽器載入完 jQuery 文件后,自調 用匿名函數會立即開始執行,初始化 jQuery 的各個模塊。相關代碼如下所示:

(function( window, undefined ) {

var jQuery = ...

// ...

window.jQuery = window.$ = jQuery;

})(window);

上面這段代碼涉及一些 JavaScript 基礎知識和編碼習慣,下面以提問的方式來逐一分析。

為什麼要創建這樣一個自調用匿名函數 ?

  • 通過創建一個自調用匿名函數,創建了一個特殊的函數作用域,該作用域中的代碼不會和已有的同名函數、方法和變數以及第三方庫衝突。

  • 由於 jQuery 會被應用在成千上萬的 JavaScript 程序中,所以必須確保 jQuery 的代碼不會受到其他代碼的干擾,並且 jQuery 不能破壞和污染全局變數以至於影響到其他代碼。這一點是任何一個 JavaScript 庫和框架所必須 具備的功能。

  • 注意,在這個自調用匿名函數的最後,通過手動把變數 jQuery 添加到 window 對象上, 明確地使變數 jQuery 成為公開的全局變數,而其他的部分將是私有的。

  • 另外,自調用匿名函數還可以有兩種等價的寫法,如下所示(注意加了底紋的圓括弧的 位置):

// 寫法 1(常見寫法,也是 jQuery 所採用的) ( function() {

// ...

} )();

// 寫法 2

( function() {

// ...

}() );

// 寫法 3 !function() {

// ...

}();

為什麼要為自調用匿名函數設置參數 window,並傳入 window 對象?

  • 通過傳入 window 對象,可以使 window 對象變為局部變數(即把函數參數作為局部 變數使用),這樣當在 jQuery 代碼塊中訪問 window 對象時,不需要將作用域鏈回退到頂 層作用域,從而可以更快地訪問 window 對象,這是原因之一;另外,將 window 對象作 為參數傳入,可以在壓縮代碼時進行優化,如下:

(function(a,b){ ... })(window);

// 參數 window 被壓縮為 a,參數 undefined 被壓縮為 b

什麼要為自調用匿名函數設置參數 undefined ?

  • 特殊值 undefined 是 window 對象的一個屬性,例如,執行下面的代碼將會彈出 true:

alert( "undefined" in window ); // true

  • 通 過 把 參 數 undefined 作 為 局 部 變 量 使 用, 但 是 又 不 傳 入 任 何 值, 可 以 縮 短 查 找 undefined 時的作用域鏈,並且可以在壓縮代碼時進行優化,如前面代碼所示,參數 undefined 會被壓縮為 b。

  • 另外,更重要的原因是,通過這種方式可以確保參數 undefined 的值是 undefined,因為 undefiend 有可能會被重寫為新的值。可以用下面的代碼來嘗試修改 undefined 的值。

undefined = "now it's defined"; alert( undefined );

注意到自調用匿名函數最後的分號(;)了嗎?

  • 通常在 JavaScript 中,如果語句分別放置在不同的行中,則分號(;)是可選的,但是對 於自調用匿名函數來說,在之前或之後省略分號都可能會引起語法錯誤。例如,執行下面的 兩個例子,就會拋出異常。

  • 例 1 在下面的代碼中,如果自調用匿名函數的前一行末尾沒有加分號,則自調用匿名 函數的第一對括弧會被當作是函數調用。

var n = 1

( function(){} )()

// TypeError: number is not a function

  • 例 2 在下面的代碼中,如果未在第一個自調用匿名函數的末尾加分號,則下一行自調 用匿名函數的第一對括弧會被當作是函數調用。

( function(){} )()

( function(){} )()

// TypeError: undefined is not a function

所以,在使用自調用匿名函數時,最好不要省略自調用匿名函數之前和之後的分號。


防止閱讀疲勞,歡迎大家持續關注。號內有多個專題,小程序(持續更新中),Javascript(完結),Vue(視頻),JQuery(持續更新)等學習資源。覺得有收穫的可以收藏關注,歡迎騷擾,一起學習,共同進步。


我的小程序,自律更自由,如果你也喜歡鍛煉的話在這裡尋找你的小夥伴吧。

一隻喜歡鍛煉的程序猿,嘿嘿。

你都看到這了,不點個關注就過分了哈~

Advertisements

你可能會喜歡