zoukankan      html  css  js  c++  java
  • jQuery源码笔记(一):jQuery的整体结构

    jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用的东西,为开发者提供了优美短小而精悍的类库。其使用简单,文档丰富,而且性能高效,能极大地提高 web 系统的开发效率。因此可以说是 web 应用开发中最佳的 Js 辅助类库之一。大部分开发者正在抛弃 Prototype,而选择Jquery 做为他们进行 web 开发的 JS 库。

    如是开发人员仅仅只知道文档中的简单的使用方法,却不明白 Jquery 的运行原理和内部机制,在使用 jquery 时,肯定会碰到许多的问题。这些问题有一部分是 Jquery 的 Bug。大部分是自身的使用不当而造成的。而文档的简单的使用说明很难解决问题。在调试基于 jQuery 的 web 应用时,很多时候都要跟踪进入jQuery 对象分析其运行状态以了解出错的原因。
    如果对于 web 的应用的页面运行性能和效率有所要求的话,那么我们更应该去明白其运行机理和核心源码。
    而且,学习jQuery源码的设计思想也是会有很大的收获的。
     
    本笔记以jQuery-2.0.3源码为准:
     
    先把笔记(一)分三部分介绍:最终将会得出整个jQuery的基本结构
    一、
    介绍:
    jQuery源码框架组成 匿名函数自执行的优点 匿名函数对外接口设置 window下挂载$()与jQuery() jQuery.prototype 原型、jQuery 基于面向对象的程序 jQuery函数调用与jQuery对象调用方法 jQuery中继承方法:extend jQuery扩展工具方法:$.trim()、$.proxy()…… 静态方法和实例方法的关系和区别简要说明。
     
    由于源码过于庞大复杂,所以先把基本框架搭出来:
    整个代码都包含在一个自执行的函数里面:
    (function(){
    
    })();

    这样有什么好处呢?

    就是在函数里面写的任何东西都是局部的,在外部都是无法用到里面的变量和方法的。这样就可以与其他代码防止冲突,互相不影响。

    但是都把东西弄成局部的也不行,还得提供接口:有一种方法就是把要对外提供的接口给它挂载到window下面,这时候调用就可以直接用了:

      (function(){
        var a = 10;
        function $(){
          alert(a);
        };
        window.$ = $;
      })();
    
      $();

    给出源码的基本结构:

    (function(){
    
      [21,94]:变量和方法;jQuery = function(){};
    
      [96,280]:给jQuery这个对象添加一些方法和属性;
    
      [285,347]:extend JQ的继承等等
    
      [349,817]:jQuery.extend({{}):拓展一些工具方法

    [877,2856]:完成一个Sizzle的功能

      [2880,3042]:jQuery当中的回调对象callbacks:通过回调函数去管理函数,即函数的统一管理 [
    8826]:window.jQuery = window.$ = jQuery; })()

    [21行,94行]:定义了一系列的变量和函数。

    [61行]:jQuery = function(){}; 这个jQuery就是平时咱们用的$()或者jQuery()去找元素的一个对外的接口。但是它目前是一个局部函数,要怎么样才能在外面找到它呢?这是就要对外提供一个接口,就在[8826行],把函数挂载在了window下的jQuery或者$。

    [96行]:jQuery.fn = jQuery.prototype = {};因为原型prototype在JavaScript中是属于面向对象的东西,所以可以说jQuery就是一个基于面向对象的东西。为什么jQuery是一个基于面向对象的程序:可以使用类比来说一下,可以说这样写可以提高可读性吧。

    比如我们平时在用jQuery的时候,写法是这样的:
    $(".div").css();
    $(".div").html();
    就好比:
    var arr = new Array();
    arr.sort();
    arr.splice();
    这都是一种面向对象的写法

    不过这里$(".div")是函数调用,只是它的执行结果是对象:[63行]如下:

    jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
    }
    //返回的是一个jQuery对象

    [285,347]:extend这个是一个继承的方法。使用继承方法更加有利于代码的独立性、后期的维护还有拓展;

    [349,817]:jQuery.extend({{}):拓展一些工具方法。拓展工具方法优势什么呢?如下:

    在jQuery当中提供了两种代码操作方式
    比如:
    $().css();
    $().html();$()是对象,所以两个方法属于实例的方法。可以看做是更高级的东西
    
    $.trim();
    $.proxy();$只是一个函数,函数下面拓展一些静态的方法。这个就叫拓展工具方法。与上面的区别就是即可以给jQuery用,也可以给原生的JS来用。可以看做是更底层的东西

    二、

    介绍:jQuery中近2000多行:Sizzle选择器 jQuery中的Sizzle:复杂选择器的实现 jQuery中的Callbacks:JQ中的回调对象(函数统一管理) jQuery中的Deferred:延迟对象(异步统一管理) jQuery中的support:浏览器功能检测。

    [877,2856]:完成一个Sizzle的功能。

    sizzle的作用就是:复杂选择器的实现。我们平时做一些比如这样类名的选择器都是$(".div")都是比较简单的,还有复杂的:$("ul li + p input.class")。他也可以是一个独立的东西,平时不使用jQuery的时候也可以用它,http://sizzlejs.com/

    /*!
     * Sizzle CSS Selector Engine v1.9.4-pre
     * http://sizzlejs.com/
     *
     * Copyright 2013 jQuery Foundation, Inc. and other contributors
     * Released under the MIT license
     * http://jquery.org/license
     *
     * Date: 2013-06-03
     */

    [2880,3042]:jQuery当中的回调对象callbacks:通过回调函数去管理函数,即函数的统一管理。

    为什么要管理:因为函数又多又复杂,统一管理起来可以方便使用。如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script type="text/javascript" src="jquery-2.0.3.js"></script>
        <script type="text/javascript">
            function fn1(){alert("1");}
            function fn2(){alert("2");}
    
            var cb = $.Callbacks();
    
            cb.add(fn1);
            cb.add(fn2);
    
            cb.fire();   //1,2.统一地放在一起
        </script>
    </head>
    <body>
    </body>
    </html>

    不止这些,还有执行一次啊、去重啊、删除啊等等。Callbacks可以加参数的。如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script type="text/javascript" src="jquery-2.0.3.js"></script>
        <script type="text/javascript">
            function fn1(){alert("1");}
            function fn2(){alert("2");}
    
            var cb = $.Callbacks();
    
            cb.add(fn1);
            cb.add(fn2);
    
            cb.fire();   
    
            cb.remove(fn1);
    
            cb.fire();
        </script>
    </head>
    <body>
    </body>
    </html>

    对函数的管理非常有帮助。

    [3043,3183]:实现的功能是:延迟对象:Deferred。作用就是对异步的统一管理。

    因为JS中异步方式很多,这样做有利用管理。比如:

            setTimeout(function(){
                alert("1");
            },1000);
            alert("2");

    先弹2,在弹1。但是正常的逻辑思维应该是先写先执行,后写后执行,这样容易看懂,后期维护也方便。如果没有延迟对象的管理,要实现这样的弹出顺序就得这样写了:

            setTimeout(function(){
                alert("1");
                alert("2");
            },1000);

    这样就非常别扭了,影响开发。延迟对象就可以解决这样的问题:

            var dfd = $.Deferred();
    
            setTimeout(function(){
                alert("1");
                dfd.resolve();
            },1000);
    
            dfd.done(function(){
                alert("2");
            })

    这样就会先出1再出2了。

    利用回调的方式:先把dfd.done()里面的参数保存,但触发了dfd.resolve()后就会执行done()里面的参数。所以如果将dfd.resolve()这句去掉的话就不会弹出2了。

    [3184,3295]:support:功能检测。

    什么是功能检测呢:有时我们会判断浏览器的版本等信息来决定执行什么样的操作,但是现在的浏览器更新非常快,功能也层出不穷。所以如果只是单单判断浏览器的版本等信息对维护是非常不利的。但是我们如果根据功能来判断浏览器就比较靠谱了,因为浏览器升级过程中功能肯定会保留。比如:

    [3198行]
        // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
        // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
        support.checkOn = input.value !== "";

    当我们写input的类型为checkbox/radio的时候,浏览器会默认为“on”,但是老版本webkit默认为“”,所以要区分老版本webkit和其他浏览器就可以通过support.checkOn了。

    三、

    介绍:jQuery中的data:数据缓存(避免大数据量的元素挂载、预防内存泄露) jQuery中的queue、dequeue:队列管理(入队、出队管理) jQuery中的attr、prop、val、addClass等:元素属性操作 jQuery中的on、trigger等:事件操作的相关方法 jQuery中的DOM操作:添加、删除、获取、包装、筛选…… jQuery中的CSS方法:样式的操作 jQuery中的数据提交与ajax:跨域、请求script、ajax…… jQuery中的animate:运动方法的实现 jQuery中的offset:位置与尺寸的方法 jQuery中的模块化:jQuery中支持模块化的模式。

    [3308,3652]:data()方法的功能:数据缓存。就是对数据进行的一些操作:获取、设置、删除。如下:(当然这种方式只是举例,实际并不这么用)

            $(".div").data('name','hello');  //添加一个数据
    
            $('.div').data('name');    //获取一个数据

    [3653,3797]:queue():队列管理;dequeue():出队

    jQuery中哪里会用到呢:比如运动的效果,如下:

    $('.div').animation({left:100});
    $('.div').animation({top:100});
    $('.div').animation({300});

    先left、再top、最后再width,就是利用队列来保证顺序的。

    [3803,4299]:attr(),prop(),val(),addClass()等等方法:对元素属性的操作。

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

    [5240,6057]:DOM操作方法:添加,删除,获取,包装,DOM筛选。

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

    [6621,7854]:提交的数据和AJAX操作:ajax(),load(),getJson().

    [7855,8584]:animate():运动方法。

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

    [8804,8821]:jQuery支持模块化的一个模式。

    最终的结构如下:

    (function(){
        
        (21 , 94) 定义了一些变量和函数 jQuery = function(){};
        
        (96 , 283) 给JQ对象,添加一些方法和属性
        
        (285 , 347) extend : JQ的继承方法
        
        (349 , 817) jQuery.extend() : 扩展一些工具方法
        
        (877 , 2856)  Sizzle : 复杂选择器的实现 
        
        (2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理
        
        (3043 , 3183) Deferred : 延迟对象 : 对异步的统一管理
        
        (3184 , 3295) support : 功能检测
        
        (3308 , 3652) data() : 数据缓存
        
        (3653 , 3797) queue() : 队列方法 : 执行顺序的管理 
        
        (3803 , 4299) attr() prop() val() addClass()等 : 对元素属性的操作
        
        (4300 , 5128) on() trigger() : 事件操作的相关方法
        
        (5140 , 6057) DOM操作 : 添加 删除 获取 包装 DOM筛选
        
        (6058 , 6620) css() : 样式的操作
        
        (6621 , 7854) 提交的数据和ajax() : ajax() load() getJSON()
        
        (7855 , 8584) animate() : 运动的方法
        
        (8585 , 8792) offset() : 位置和尺寸的方法
        
        (8804 , 8821) JQ支持模块化的模式
        
        (8826)  window.jQuery = window.$ = jQuery;
        
    })();
  • 相关阅读:
    [转]Angular4首页加载慢优化之路
    [转]angular 禁止缓存
    微服务之分布式跟踪系统(springboot+pinpoint)
    分布式追踪系统设计与实现
    QLExpress 规则引擎使用介绍
    几个常见规则引擎的简单介绍和演示
    大数据对账
    美团配送资金安全治理之对账体系建设
    美的支付-对账系统实现
    redis实现对账(集合比较)功能
  • 原文地址:https://www.cnblogs.com/Chen-XiaoJun/p/6217789.html
Copyright © 2011-2022 走看看