美文网首页
[No.5 jQuery源码解析—逐段解析(5)

[No.5 jQuery源码解析—逐段解析(5)

作者: web_无笙 | 来源:发表于2017-11-10 20:37 被阅读0次

    今天,更新有点晚,

    但是干货不怕晚,

    接着昨天讲得讲,

    把第一段讲的没讲完的继续讲解。

    (function(){

            (21 , 94定义了一些变量和函数 jQuery = function(){};

            (96 , 283给JQ对象添加一些方法和属性

            (285 , 347extend : JQ的继承方法

            (349 , 817jQuery.extend() : 扩展一些工具方法

            (877 , 2856)  Sizzle : 复杂选择器的实现

            (2880 , 3042Callbacks : 回调对象 : 对函数的统一管理

            (3043 , 3183Deferred : 延迟对象 : 对异步的统一管理

            (3184 , 3295support : 功能检测

            (3308 , 3652data() : 数据缓存

            (3653 , 3797queue() : 队列方法 : 执行顺序的管理

            (3803 , 4299attr() prop() val() addClass() : 对元素属性的操作

            (4300 , 5128on() trigger() : 事件操作的相关方法

            (5140 , 6057DOM操作 : 添加 删除 获取 包装 DOM筛选

            (6058 , 6620css() : 样式的操作

            (6621 , 7854提交的数据和ajax() : ajax() load() getJSON()

            (7855 , 8584animate() : 运动的方法

            (8585 , 8792offset() : 位置和尺寸的方法

            (8804 , 8821JQ支持模块化的模式

            (8826)  window.jQuery = window.$ = jQuery;

        })();

    接下来,我们看到32-35行这一块,

    // Use the correct document accordingly with window argument (sandbox)

        location = window.location,

        document = window.document,

        docElem = document.documentElement,

    它是把window下的一些进行变量存储,

    比如location啊,documentElement啊变量存储,

    就是说不存储的话,平时就可以这么去用,

    我们打开压缩版本可以看到,

    这里的这个i就是window.location

    这样有利于版本的压缩,对压缩很有意义,

    前面的locationdocument就不讲了,

    这个docElemdocument

    其实document就是页面节点当中的HTML标签,

    就是用来存一下它,在下边都会有用的。

    然后,继续看下边两句话,

        // Map over jQuery in case of overwrite

        _jQuery = window.jQuery,

        // Map over the $ in case of overwrite

        _$ = window.$,

    其实这两句话的意思就是:
    它是和我们防止冲突,有一定关系的,

    jQuery中防止冲突就会用到这两个变量,

    好,等到咱们讲到防冲突的时候,

    再给大家详细讲解它俩,

    现在,我先简单的说一说,

    比如说我们在使用jQuery的时候,

    <!-- 先引入jQuery文件 -->

    <script src="jquery-2.0.3.js"></script>

    <script>

        //  jQuery对外听供的接口

        // #() 和 jQuery() 这两个方法

    </script>

    这个$ 其实是jQuery的一个简写方式,

     尤其是这个$,在很多库当中都会使用到它,

    这时候就会出现冲突,

    比如说其他库中,也有一个$,比如说:

    <script>

               var $ = 10;

    </script>

    <!-- 先引入jQuery文件 -->

    <script src="jquery-2.0.3.js"></script>

    这个$ 就会影响到jQuery

    它有个防冲突的方法,

    就是利用那两个变量才能避免,

    如果说代码是这么写的话,

    先走上面,再走下面吗,

    走到下面的时候,

    这时候的window.$存的就是10,

    如果没这两个变量这会儿存的就是undefined

    这会上面根本不存在这 两个东西,

    跟冲突有关的,到时讲到这个方法的时候,

    防冲突的方法在扩展工具方法哪里涉及到的,

    到那个时候咱们再来详细地讲解。

    咱们接着往下面看,

        // [[Class]] -> type pairs

         class2type = {},

    这里定义了一个空的对象字面量,

    我们先看它的名字,class2type这个是跟类型有关的,

    这个变量在jQuery当中去使用$.type()的工具方法,

    判断每个变量和元素的类型所用到的这个变量,

    它最终会成为什么样的呢?咱们的类型判断,

    class2type = {'[Object String]':'string','[Object Array]':'array'}

    这里面会存成这样一个形式,

    其实这一块都是用于类型判断的,

    那到咱们讲类型判断的时候再来详细地讲解,

    所以说为什么是class2type

    因为这里是两个字符串格式。

    我们继续看到下面,

        // List of deleted data cache ids, so we can reuse them

        core_deletedIds = [ ],

        core_version = "2.0.3",

    在这里肯定跟数组有关的,

    我们也能看得出来,

    定义了一个空数组,

    根据这个注释,我们也能看得出来,

    这里是跟缓存数据有关的,

    其实,这个变量里面有个deletedIds,

    就是删除id的意思,

    这个在之前的版本确实和删除Id有关的,

    但是在这2.0.3的版本中,

    这个时候,这数据存储的方法就没有用了,

    改成了面向对象的写法了,

    所以说用不上删除id的方式了,

    所以,这咱只是知道一下就行了。

    接着,咱们再来往下看,

    // Save a reference to some core methods

        core_concat = core_deletedIds.concat,

        core_push = core_deletedIds.push,

        core_slice = core_deletedIds.slice,

        core_indexOf = core_deletedIds.indexOf,

        core_toString = class2type.toString,

        core_hasOwn = class2type.hasOwnProperty,

        core_trim = core_version.trim,

    这里是把常用的数组啊、对象字面量啊、

    字符串下面这些方法进行了局部变量的存储,

    可以很方便地在后面使用,对于压缩很有帮助。

    上边的之前也讲过,我们来说说最后这个,

    这个trim是去掉字符串的前后空格,

    在之前老版本的浏览器下这个方法是没有的,

    我们只能用正则去写,才能去掉前后空格,

    在高级浏览器中是有的,我们可以直接拿来用,

    所以,我们简单地来看一下怎么拿来用,

    // 比如,我们在这里先写个字符串

    // 在前后加一些空格

    // 我可以在两边加一个小括号,才能看出空格

    alert('('+'   1111   '+')')

    结果如下:

    很明显能看出前后空格,

    如果说直接在字符串内调用trim方法,

    alert('('+'   1111   '.trim()+')')

    结果如下:

    是不是,就去掉了前后的空格,

    所以在高级浏览器下,

    咱们可以直接调用这个方法。

    下边呢,我们看到了jQuery这个函数,

    // Define a local copy of jQuery

        jQuery = function( selector, context ) {

            // The jQuery object is actually just the init constructor 'enhanced'

            return new jQuery.fn.init( selector, context, rootjQuery );

        },

    前面我们总结框架结构的时候给大家说过,

    这个jQuery函数就是对外提供的方法接口,

    通过挂在到window上,

    可以在闭包外面进行查找,

    前面,我们也说过,

    这个函数执行过后会返回的是对象,

    返回对象的时候,

    这个对象后边才能节对象所拥有的方法,

    为什么这个构造函数不用其他的,

    却还是用jQuery相关的,

    我们看下下面的源码,

    // 96行

    jQuery.fn = jQuery.prototype = {

    这里可以看出,fn就是jQuery的原型,

    咱们先来说说普通写面向对象的方法,

    // 比如,我们在这里先写个字符串

    // 在前后加一些空格

    // 我可以在两边加一个小括号,才能看出空格

    // alert('('+'   1111   '.trim()+')')

    // 先写个构造函数

         function Aaa(){

    };

    // 然后在这个构造函数下面添加原型

    // 一般我们都会写一个初始化的方法

    // 让程序调用的时候就可以执行了

        Aaa.prototype.init = function(){

    };

    // 然后添加下原型下的其它方法

         Aaa.prototype.css = function(){

    };

    // 咱们在下面new一个构造函数

    // 就能创建一个出一个对应的对象

        var a1 = new Aaa();

    // 创建好这个对象之后

    // 有初始化方法,我们就要先初始化一下

    // 这个代码就执行了

        a1.init();

    // 执行过后,就能通过a1来调用css方法或其它的方法

        a1.css();

    大体上,面对对象就是这样的,

    但在jQuery当中没有这样,

    它是这样做的,

    // 比如说还是先写一个构造函数

    function jQuery(){

                return new  jQuery.prototype.init();

    };

    jQuery.prototype.init = function(){

    };

    jQuery.prototype.css = function(){

    };

    // jQuery是这样调用的

        jQuery().css();

    当调用的时候,

    return后的那句话就会执行,

    这句话一执行,这个函数就会执行,

    这个函数一执行,就说明初始化方法就调用了,

    jQuery中你这样去调用后,

    就不需要初始化的步骤了,

    而且直接返回的是对象,

    就说明直接调用是不是就创建出来这个a1了呀,

    这个对象就能拥有css的方法了,

    所以说看一下jQuery

    就很方便的解决了之前的这种繁琐的操作,

    一目了然就能找到css

    细心的小伙伴会发现,

    我这里说的好像有问题,

    它怎么能找到css方法的呢?

    这个确实光这么去写是有问题的,

    其实在jQuery当中我们可以找到这句话,

    // 283行

    // Give the init function the jQuery prototype for later instantiation

    jQuery.fn.init.prototype = jQuery.fn;

    注意这里的fn就是原型,

    如果把这句话加到里面,

    // 比如说还是先写一个构造函数

    function jQuery(){

                return new  jQuery.prototype.init();

    };

    jQuery.prototype.init = function(){

    };

    jQuery.prototype.css = function(){

    };

    jQuery.fn.init.prototype = jQuery.prototype;

    // jQuery是这样调用的

        jQuery().css();

    这样就可以了,对吧!

    因为,是把这个jQuery原型

    给这个构造函数初始化下边的原型,

    那就形成了一个对象的引用,

    所以说把一个对象赋给另一个对象的话,

    这样的话就出现了一个对象的引用的关系,

    我们在后面或前面的构造函数原型上进行修改的话,

    其实是一样的,对吧!

    这就是jQuery中的一个设计方式。

    就可以形成这样的调用方式。

    下边是很多正则,

        // Used for matching numbers

        core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

    首先的这个正则的作用是去找匹配数字的,

    包括正负数、带不带小数点,

    而且还包括科学计数法,比如很大的一个数字,

    可以通过科学计数法去表示,

    这个正则会在后面使用,到时咱们再说。

        // Used for splitting on whitespace

        core_rnotwhite = /\S+/g,

    这个正则是匹配单词的有关的,

    去找元素没有空格分隔开的。

    // A simple way to check for HTML strings

        // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)

        // Strict HTML recognition (#11290: must start with <)

        rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

    这个正则前面在或之前匹配的是一个标签,

    比如,我们创建标签的时候会用到这个正则,

    后面这一块是匹配id的形式,

    我们可以看它的注释,

    它是防止xss注入,

    通过locationhash值,

    我们都知道XSS是注入木马的一种方式,

    比如输入框留言板有漏洞,

    他可以输入一段木马程序,

    你一点击就上传或者就执行了,

    这时候是非常危险的,

    比如我们去做hash值改变的时候,

    有可能会遇到类似的问题。

        // Matches dashed string for camelizing

        rmsPrefix = /^-ms-/,

        rdashAlpha = /-([\da-z])/gi,

    我们看第一个ms是什么意思,

    这是IE的一个前缀,

    它除了匹配字母也能匹配数字,

    比如说 -2d就可以转成2d

    这都是跟CSS3有关的,

    这一块,我没有讲的特别详细,

    如果对正则有不熟悉的,

    可以看我之前发的正则的内容进行学习。


    OK,咱们这段暂时讲到这里!


    回看上一集:

    原文中此处为链接,暂不支持采集


    别走开,下集更精彩。

    喜欢文章的小伙伴,

    希望大家多多转发分享,

    你的分享就是我的动力!

    喜欢 分享 or

    相关文章

      网友评论

          本文标题:[No.5 jQuery源码解析—逐段解析(5)

          本文链接:https://www.haomeiwen.com/subject/wqeimxtx.html