jQuery源碼研究——解決命名衝突

在項目中不免不去使用多個插件,如此一來這些插件就有可能出現同樣的名稱,當出現同名變量時後一個將會覆蓋上一個,這樣的話咱們就沒法同時使用多個插件了。javascript

當遇到這種狀況咱們能夠手動去修改插件源碼把它的名字改了,但這種方式是不明智的,假如說你使用的某個插件它的版本更新了,那麼你還得再次去修改它的源碼,再則隨意去修改插件源碼對團隊來講是混亂不堪的,所以最好的方式應該是由插件自身來解決命名衝突,在jQuery中有一個noConflict方法,這個方法就是用來解決命名衝突的。java

jQuery.noConflictjquery

var _jQuery = window.jQuery,
    _$ = window.$;
jQuery.noConflict = function( deep ) {
    if ( window.$ === jQuery ) {
        window.$ = _$;
    }
    if ( deep && window.jQuery === jQuery ) {
        window.jQuery = _jQuery;
    }
    return jQuery;
};
if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
}
return jQuery;

代碼中的window是全局的,jQuery是局部的,window.jQuery把全局中的jQuery保存下來,window.$的做用同上,將全局中的jQuery和$保存下來是爲了當咱們使用jQuery.noConflict方法時好將$和jQuery還原成以前的,由於在沒有使用jQuery.noConflict方法前,全局的$和jQuery已經被我們強大的jQuery給覆蓋了,所以若是你不使用jQuery.noConflict方法將沒法使用以前的那個插件,那麼當咱們使用jQuery.noConflict方法後jQuery不就被其餘插件給覆蓋了嗎,插件確實會把jQuery給覆蓋,不過在jQuery.noConflict方法中,它最後又將jQuery返回了,所以咱們只須要將這個返回的jQuery取一個新的名字就行了。git

所以咱們能夠看出jQuery在解決命名衝突上它是先將插件保存下來,而後使用本身的jQuery將插件覆蓋,當調用jQuery.noConflict方法時再將插件放出並將本身返回。github

須要注意的是此方法只能解決在jQuery以前導入的插件,由於若是在jQuery以後導入,那麼jQuery就已經被覆蓋了,天然也就沒法使用noConflict方法。ui

在解決命名衝突方面,當jQuery檢查到咱們有使用CommonJS時,$和jQuery將不會暴露到window中,具體代碼就是下面這句了this

if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
}

這個noGlobal是從這裏傳過去的插件

( function( global, factory ) {
    "use strict";
    // 判斷是否有使用CommonJS
    if ( typeof module === "object" && typeof module.exports === "object" ) {
        module.exports = global.document ?
            // true:不在window上暴露$和jQuery,所以使用CommonJS後你將沒法在全局調用jQuery
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ){
  // 省略
});

jQuery.noConflict註釋版code

var
    // 將全局jQuery保存起來
    _jQuery = window.jQuery,
    // 將全局$保存起來
    _$ = window.$;
    // 解決命名衝突 當傳遞一個true值則會將$和jQuery命名權限都交出
jQuery.noConflict = function( deep ) {
    // 若是如今使用的是jQuery則將$權限交出,給其餘插件使用
    if ( window.$ === jQuery ) {
        window.$ = _$;
    }
    // 若是deep爲true而且使用的是jQuery則將jQuery命名權限交出,給其餘插件使用
    if ( deep && window.jQuery === jQuery ) {
        window.jQuery = _jQuery;
    }
    // 返回jQuery,咱們能夠去從新命名
    return jQuery;
};

// 暴露jQuery和$標識符
// 關於在全局暴露jQuery的相關討論:https://github.com/jquery/jquery/pull/557
if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
}
return jQuery;
} );
相關文章
相關標籤/搜索