JS的框架有很多,不可避免的,在引用多種框架的時候,就需要進行變量名的爭奪。其中以$符最爲常見。在jQuery中,$是Window.jQuery對象的一個引用,即使$符與其他框架產生衝突,也保證了jQuery對象能夠使用。那麼,在引用多種框架的時候,jQuery又是如何避免這種衝突呢?jQuery採用了noConflict()方法來實現對控制權的移交。
我們先來試着打印一下$
<script type = "text/javascript">
alert($);
/*
function ( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
}
*/
</script>
再來看看jQuery:
<script type = "text/javascript">
alert(jQuery);
/*
function ( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
}
*/
</script>
調用$.noConflict()
<script type = "text/javascript">
$.noConflict();
alert($);//undefined
</script>
打印$,返回了undefined,可以看出,現在jQuery已經釋放了對$的引用。
jQuery.noConflict 方法包含一個可選的布爾參數,用以決定移交 $ 引用的同時是否移交 jQuery 對象本身:
jQuery.noConflict([removeAll])
當傳入true時,會同時移交jQuery對象本身
<script type = "text/javascript">
$.noConflict(true);
alert($);//undefined
alert(jQuery);//undefined
</script>
我們也可以給jQuery對象取別名:
<script type = "text/javascript">
var Kingsley = $.noConflict();
Kingsley('p').hide();
</script>
但是,我們並不是非常願意將簡單的$拱手相讓,那麼,可以這樣做:
jQuery(document).ready(function($) {
$('p').hide();
});
// 使用其他庫的 $ 的代碼
alert($);//undefined
到這裏,我們有必要來看看jQuery的源代碼是如何實現noConflict()的了:
var
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};
jQuery 通過兩個私有變量_jQuery和_$,映射了 window 環境下的 jQuery 和 $ 兩個對象,用來臨時存儲Window.jQuery 和 Window.$,以防止變量被強行覆蓋。當deep沒有被設置,執行 noConflict 會將變量 $ 的控制權移交給第一個產生 $ 的庫。_$ 覆蓋 window.$,此時 jQuery 別名 $ 失效,但 jQuery 本身完好無損。它的控制權就完全交接出去了。反之如果 deep 設置爲 true 的話,_jQuery 覆蓋 window.jQuery,此時 $ 和 jQuery 都將失效。