对JQuery的深入理解(上)- 兼容CommonJS和CommonJS-like

一、兼容CommonJS和CommonJS-like

1.什么是CommonJS

它是一种JavaScript(以下全部称为js)语言的模块化规范,是一种思想,其最终目标在于使js能够在更多环境下运行,而不只是浏览器

CommonJS是一种不同于普通js的规范,它使得js具有模块化,能够脱离浏览器来执行js语句

2.为什么兼容

在一般js中,调用jquery(以下全部称为jq)方法是需要将jq对象挂接到全局的window对象上的,而在CommonJS中,没有现成的window对象,但可以通过require来获取jq对象

3.module对象

在Node.js中,Module是一个构建函数,所有的模块儿都是此函数的实例。每个模块内部都有一个module对象,代表当前模块,其中module.exports属性是用来对外输出值,将接口暴露出去

4.源码
( function( global, factory ) {
    "use strict";
    if ( typeof module === "object" && typeof module.exports === "object" ) {
        module.exports = global.document ?
            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 ) {

    //此处省略各种方法
    
    if ( typeof noGlobal === "undefined" ) {
        window.jQuery = window.$ = jQuery;
    }
    return jQuery;
});
5.解读源码
  • 整体结构

    ( function( global, factory ) {
    
    })( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
        return jQuery;
    });
    

    整体来看这是一个(function(){})()结构的立即执行函数,这是一个匿名函数,这个函数可以自己进行执行,匿名函数最大的优点是不会造成全局变量污染

    (function(arg1,arg2){
        
    })(param1,param2)
    //相当于
    function test(arg1,arg2){ //上面是一个匿名函数,为了更好的表达,我将给函数起一个名字
        
    }
    test(param1,param2);
    
  • “use strict”;

    这是js的严格模式,其作用是使得js代码运行时实行更加严格的解析和错误的处理,详细内容请自己查询

  • 代码解读1

    ( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    
        //此处省略各种方法
        
        if ( typeof noGlobal === "undefined" ) {
            window.jQuery = window.$ = jQuery;
        }
        return jQuery;
    });
    
    • 这里是调用了匿名的函数,然后将两个值传进去,typeof window !== "undefined" ? window : this是第一个参数,function( window, noGlobal )这整个函数是第二个参数

    • 第一个参数判断当前是否存在window对象,如果存在就把该对象传给global,否则将当前对象传给global;

    • 第二个参数是jq的工厂函数,其中包含了所有jq方法,将该函数传给了factory

    • 在第二个参数方法中,判断了是否定义了noGlobal,若有则直接返回jq对象,否则将jq对象添加到window中

  • 代码解读2

    ( function( global, factory ) {
        "use strict";
        if ( typeof module === "object" && typeof module.exports === "object" ) {
            module.exports = global.document ?
                factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
        } else {
            factory( global );
        }
    } )
    
    • 这是一段匿名函数,其作用就是判断当前运行环境,将js对象以不同的方式暴露
    • global是全局的意思,factory是工厂的意思,很明显global是一个全局变量,factory是jq的工厂变量
    • 首先判断是否存在module是否为对象,并且module中的module.exports是否为对象,其实就是判断module中是否存在exports,也就是判断当前是否在CommonJS环境中,若在CommonJS环境中,则将jq对象赋给module.exports来暴露jq对象
    • 其中global.document用来判断当前是否存在document对象(比如Node.js没有该属性),也就是判断此时是否在浏览器运行,若在浏览器运行则直接调用factory方法来创建jq对象(这里有两个参数,第二个用来跳过代码解读1中的添加window属性)赋值给module.exports,否则构建一个函数用来接收window对象并赋值给module.exports,判断传入的window是否有document属性,没有报告错误,有则执行factory方法(没有第二个参数,所以noGlobal没有定义)将jq添加到window中
    • 如果不是在CommonJS环境中,则直接调用factory方法来将jq对象添加到window中
  • 总之,jq强制了当前环境必须存在window对象,并将jq对象添加到window中

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会功夫的李白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值