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;
} );
相关文章
相关标签/搜索