來源:淘寶UED
許多的JS 框架類別庫都選擇使用$ 符號作為函數或變數名稱 ,jQuery 是其中最為典型的一個。在 jQuery 中,$ 符號只是 window.jQuery 物件的一個引用,因此即使 $ 被刪除,window.jQuery 仍然是保證整個類別庫完整性的堅強後盾。 jQuery 的 API 設計充分考慮了多框架之間的引用衝突,我們可以使用 jQuery.noConflict 方法來輕鬆實現控制權的移交。
jQuery.noConflict 方法包含一個可選的布林參數[1],用於決定移交$ 引用的同時是否移交jQuery 物件本身:
#
1 # |
jQuery.#noConflict([ removeAll]) | #
預設情況下,執行noConflict 會將變數$ 的控制權移交給第一個產生$ 的函式庫;當removeAll 設定為true 時,執行noConflict 則會將$ 和jQuery 物件本身的控制權全部移交給第一個產生他們的庫。
例如在 KISSY 和 jQuery 混用,並且慣用 $ = KISSY 來簡化 API 操作的時候,就能夠透過這個方法解決命名衝突的問題。
那麼這個機制是如何實現的呢?閱讀 jQuery 原始碼開頭[2],首先要做的一件事情是這樣的:
JavaScript
#
# 1 2 | 3
#4
// Map over jQuery in case of overwrite# # #_jQuery = window##.jQuery ##,// Map over the $ in case of overwrite # # #_$ = window.#$, | #
容易理解的是,jQuery 透過兩個私有變數映射了 window 環境下的 jQuery 和 $ 兩個對象,以防止變數被強行覆蓋。一旦 noConflict 方法被調用,則透過 _jQuery, _$, jQuery, $ 四者之間的差異,來決定控制權的移交方式,具體的程式碼如下:
JavaScript
#
# 1 2 3 #4 #5 ##6789 |
10
noConflict: function( deep ##) { if ( window.##$#=== jQuery ) #{window.$ = _$ ;# }如果 ( 深 && 視窗.jQuery ===#jQuery ##) { #window.jQuery #=#_jQuery##;# ################ ##jQuery; #}
|
再來看上面所說的參數設定問題,如果 deep 沒有設置,_$ 覆蓋 window.$,此時 jQuery 別名 $ 失效,但 jQuery 本身完好無損。如果有其他類別庫或程式碼重新定義了 $ 變量,它的控制權就完全交接出去了。反之如果 deep 設定為 true 的話,_jQuery 覆蓋 window.jQuery,此時 $ 和 jQuery 都會失效。
這種操作的好處是,無論是框架混用還是jQuery 多版本共存這種高度衝突的執行環境,由於noConflict 方法提供的移交機制,以及本身返回未被覆蓋的jQuery 對象,完全能夠透過變數映射的方式解決衝突。
但無法避免的事實是可能導致的插件失效等問題,當然透過簡單修改上下文參數即可恢復 $ 別名:
#
JavaScript
#
# 1 2 3 | #4
#5 var #query = jQuery.noConflict(#true ##); (function ($) {// 外掛程式或其他形式的程式碼,也可以將參數設為jQuery })(query #) |
以上是淺析 jQuery 中的防衝突機制-noConflict的詳細內容。更多資訊請關注PHP中文網其他相關文章!