博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery源码分析 开篇(一)
阅读量:5869 次
发布时间:2019-06-19

本文共 3243 字,大约阅读时间需要 10 分钟。

      解读一个开源框架,最终目的当然就是学习程序的设计思想和实现技巧。

      JavaScript宗旨就是Write Less, Do More,简洁的API,优雅的链式,强大的查询与便捷的操作都是我们喜欢他的原因。作为开发人员在使用jQuery时,由于仅仅只知道jQuery文档中的使用方法,不明白jQuery的运行原理,时常会碰到许多的问题。这些问题大部分是使用不当而产生,极少数是jQuery的Bug。因此如果我们只知道使用jQuery,而不知道其原理,那就是“知其然,而不知其所以然”,不明白其中运行机理和核心源码,我们也很难写出基于jQuery类库的高性能的程序出来。

jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我尽量按照这样的顺序去学习:

 1. 读官方文档,官方有非常详细的文档说明

2. 读源码,加注释,把自己思考的过程和结果记录下来

3. 大量阅读相关的网文和书籍,比如相同主题的分析文档,网上常问的问题等

不管怎么说写一篇源码分析,记录自己的心得,加深理解,对我们来说好处不言而语。

好吧,废话不多说,开始解读(基于 jQuery 1.11 版本)。有分析或者语言表达不到位之处请指正(文笔一般)^^。 

 

分析源码:首先要看懂这个(自调用匿名函数)

任何库和框架的设计,第一个要解决的问题就是命名空间与变量污染的问题。jQuery恰好利用到了javascript的函数作用域的特性,采用IIFE立即调用表达式包裹自身的方式来解决这个问题。

(function( window, undefined ) {})(window,void 0);

通过定义这样一个匿名函数,创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏全局的命名空间。如果将匿名函数返回值(函数)赋予func,并且返回值调用匿名函数作用域上的变量,该局部变量在函数这行完之后空间不会被释放。

var func = (function( window, undefined ) {    var  i = 0            return  function(){             console.log(i++);            }})(window,void 0);

多次运行func(),你会发现i实现了自加功能。

这样确保jQuery创建的变量不能和导入的其他程序所使用的变量发生冲突,这也是jquery兼容性强大原因之一。

从jQuery各个版本来看,jQuery立即调用函数表达式使用有三种写法:

/*第一种:*/(function(global,factory){    factory(global)})(this,function(){    return function(){        //jQuery 实现    }  })/*第二种:*/var factory = function(){    return function(){        //jQuery 实现    }  }()    var jQuery = factory(); /*   这种模式类似工厂模式,只是创建了一个单例 */ /*第三种:*/(function(window,undefined){    var jQuery = function(){    }    window.jQuery = window.$ = jQuery;})(window)/* 这种写法的优势在于:  1、window和undefined都是为了减少变量查找所经过的scope作用域。当window通过传递给闭包内部之后,在闭包内部使用它的时候,可以把它当成一个局部变量2、undefined也是同样的道理,其实这个undefined并不是JavaScript数据类型的undefined,而是一个普普通通的变量名。只是因为没给它传递值,它的值就是undefined,undefined并不是JavaScript的保留字*/

对比写法1和写法3,写法3 利用写法1思想,把整个函数作为参数传递给另外一个函数,这样做的目的是主要是判断jQuery在不同平台下的加载逻辑。

当前的主流库一般都提供了对AMD和CMD的支持。jQuery也不例外,来看看代码的实现。

(function( global, factory ) {    if ( typeof module === "object" && typeof module.exports === "object" ) {//判断是否模块化引入jQuery 支持CMD规范        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 if("function" == typeof define && define.amd) { //支持 AMD              define([],factory)    }else {
factory( global );     }
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    //省略jQuery实现     return jQuery; })

 

 

接下来看看jQuery自调用匿名函数中都实现了什么功能,按照代码顺序做下排列:

(function( window, undefined ) {    var jQuery = function( selector, context ) {//构建jquery对象        return new jQuery.fn.init( selector, context, rootjQuery );    }// 工具函数 Utilities// 异步队列 Deferred// 浏览器测试 Support// 数据缓存 Data// 队列 queue// 属性操作 Attribute// 事件处理 Event// 选择器 Sizzle// DOM遍历// DOM操作// CSS操作// 异步请求 Ajax// 动画 FX    window.jQuery = window.$ = jQuery;})(window);

以上注释清晰的展现了jQuery大致结构,有了这个结构框架,就能看懂jquery能做什么(结合jQuery文档,很容易就上手)。

jQuery一共13个模块,从2.1版开始jQuery支持通过AMD模块划分,这里面各个模块也不是单一的,比如jQuery动画,都会依赖异步队列、动画队列、回调队列与数据缓存模块等。 

jQuery抽出了所有可复用的特性,分离出单一模块,通过组合的用法,不管在设计思路与实现手法上jQuery都是非常高明的(这里模块化思想值得我们借鉴与学习)

       任何程序代码不是一开始就复杂的,成功也不是一躇而蹴的。接下来章节就来分解jQuery内部各个模块,探讨各个模块功能与实现。坚持^^

 

转载于:https://www.cnblogs.com/hoboStage/p/4945954.html

你可能感兴趣的文章
高并发环境下,Redisson实现redis分布式锁
查看>>
java基础-System类常用方法介绍
查看>>
Java继承
查看>>
乌克兰基辅一世遗修道院起火 现场火光照亮夜空
查看>>
[iOS 10 day by day] Day 2:线程竞态检测工具 Thread Sanitizer
查看>>
Centos/Ubuntu下安装nodejs
查看>>
关于浏览器的cookie
查看>>
Hyper-V 2016 系列教程30 机房温度远程监控方案
查看>>
国内先进的智能移动广告聚合平台-KeyMob聚合
查看>>
我的友情链接
查看>>
ubuntu 镜像站部署
查看>>
Xshell 连接虚拟机慢 解决方案
查看>>
我的友情链接
查看>>
PHP - 如何打印函数调用树
查看>>
js闭包
查看>>
Swift笔记2
查看>>
寒假。3.3.G - Common Child (最大公共子序)
查看>>
052(四十二)
查看>>
设计模式学习笔记--原型模式
查看>>
.Net 通过MySQLDriverCS操作MySQL
查看>>