[No.4] jQuery源码解析—逐段解析

Posted 烟雨风飘渺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[No.4] 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;

    })();

第一段,21到94行,

它们定义了一些函数,

还有刚开始的匿名函数自执行,

打开jQuery源码,

/*!

* jQuery javascript Library v2.0.3

* http://jquery.com/

*

* Includes Sizzle.js

* http://sizzlejs.com/

*

* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors

* Released under the MIT license

* http://jquery.org/license

*

* Date: 2013-07-03T13:30Z

*/

上来是一些注释,

我简单地给大家说一说,

第一行:咱们使用的是jQuery2.0.3的版本,

第二行是它的官方网站,

那下边是Sizzle.js的官方网站,

前面我们说过Sizzle在jQuery中,

是一个复杂选择器的实现,

那它也是一个独立的,

所以也可以直接来用这个库,

在下边是它的版权,从05-13年,

归于jQuery基金会所有,

还有一些赞助过jQuery的人,

它也符合MIT,也有软件许可证,

说白了jQuery就是一个免费合法的一个软件,

最后是它最近更新的一个时间。

接着我们来看到,

在jQuery中,这个注释非常多,

在这些注释当中,

我们经常会看到如(#13335)

#号后面跟一串数字,

这是什么意思?

意思就是可以通过它,

找到更详细的说明,    

我们打开https://bugs.jquery.com,

然后,把这个索引放到输入框内,

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

进行搜索,

然后我们就可以看到跟这一块有关,

更加具体的说明,

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

下边还有很多人留言和讨论,

都可以查看得到。

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

再下来我们看到一行,

在之前跟大家讲过,

这个匿名函数自执行,

(function( window, undefined ) {

它的一个作用是里面的代码都是局部的,

然后呢,跟外边的代码不冲突,

就是这样一个作用,

那我们老看一下,

它为什么要把window当参数,

传到这个闭包当中,

<script>

        // 在jQuery中一上来就是一个匿名函数自执行

        (function(window){

        // 先传了一个window    

        // })(window);

        // 如果不传这个window

        // 我们直接在这个里面使用window其实也是可以的

        window

        // 那它为什么还要去传呢?

        // 有两点

        // 第一点:window是我们js的最顶端,它的查找速度比较慢

        // 根据这个作用域面的原理,变量是找离它最近定义那个变量开始查找

        // 如果找不到的话,它才会一层一层往外找

        // 所以说在你传参之后,它找是里面的这个window,不会去找外边的window  

        // 它的查找速度更快

        // })()

        // 第二点:这个window传过来之后,对于压缩版本就很有用的

        // 如果是不传window它是压缩不了的,

        })(window)

</script>

然后我们打开这个压缩版本,

可以看到,传过来的就不是window了,

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

而是e了,是吧!

所以下边用到e的都是window,

对于,压缩来说的特方便的,

这就是它为什么要传window,

对于查找和压缩都有好处。

其实在下边很多变量都是跟这个有关的,

咱们到时候读到的时候,再给大家去讲。


接着,看这个undefined,它也是传过来的,

它没有被压缩,为什么要传它呢?

首先,我们来了解一下这个undefined属性,

它既不是保留字,也不是关键字,

这个undefined在外边是可以被修改的,

// 比如我定义了一个undefined等于十

var undefined = 10;

// 然后我打印一下

console.log(undefined);

在IE10下,它是undefined,

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

在IE8下是10,

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

所以说在jQuery当中,

为了防止在外对这个undefined进行修改,

所以它进行了一个传参的形式,

如果里面使用undefined,

肯定是找这个传入的参数,

而不会找外面的,对吧,

这样就能防止被修改,

所以,需要传入一个undefined。


接下来,我们看下面这一块,

// Can't do this because several apps including ASP.NET trace

// the stack via arguments.caller.callee and Firefox dies if

// you try to trace through "use strict" call chains. (#13335)

// Support: Firefox 18+

//"use strict";

这一块写了很多的注释,

看到这句话是什么意思呢?

//"use strict";

意思是说只要写了它,

js是在一个严格的模式下,

然后我们来看一下究竟是什么意思,

假如在我们的文件中写了个它,

说明这里的js在一个严格的模式下,

在严格的模式下就是要让我们写代码要规范,

如果出现不规范的代码,这个程序就会报错,

"use strict";

a = 10;

比如我们平时写个a,如果不加var的话,

平时也是可以的,就相当于一个全局的,

但是这里添加了严格模式,就会报错。

如果把这句话注释起来,

a等于10就完全可以。

除了有这种问题以外呢,

在严格模式下有问题的特别多,

再给大家举个例子吧。

var a = 010;

比如说我们这里写的是一个八进制的数字,

在非严格模式下是不会报错的,

但是在严格模式下,就会报错,

 它是不允许写这种八进制的形式的内容,

所以这个在严格模式下,条条框框比较多,

这样有利于我们的写法。

但是在jQuery中并不推荐我们去使用它,

首先,它的兼容性有些问题,

还有就像它写的不支持.net火狐的老版本,

经常会出现假死的状态,或者.net这个跟踪有问题,

所以说他建议我们不要去使用,除非你对它很了解。

比如火狐18+就不出现火狐假死的状态了。

这个,我们平时写代码的时候没有必要去写严格模式,

写代码的时候自己多注意一下代码规范就好了。


接下来,我们看到 rootjQuery 这个变量,

这个变量的作用就是jQuery的一个跟目录,

在866行,有这么一句话,

rootjQuery = jQuery(document);

这个变量就是jQuery选择到的document元素,

那它为什么要赋给这个变量?

也是有两点考虑吧,在我看来,

首先第一个,就像刚才说的,

你去整体的赋值的话,

这个变量在压缩版本的时候,

它就可以变成一个字符,

如果说在下面的代码用jQuery(document),

它就没有办法进行压缩,是吧!

不能变成一个字符。

第二个就是我们比如说去开发的时候,

// 比如说

a = a + 10 ;

如果这样去写的话,

我们根本就不知道,

这个10代表的是什么意思,

对于代码可维护性,不是那么方便。

如果说把这个10赋值给一个变量。

var iSpeed = 10;

a = a + iSpeed ;

这时候大家就知道了,

原来这个10,表示的是速度,

所以说定义一个变量,

对于后面的维护,

有着很大的帮助。


下面这个变量是和DOM加载有关的,

    // The deferred used on DOM ready

    readyList,

所以,等到我们讲到DOM加载的时候,

再来说一下,它是干什么用的,

这个DOM加载在我们的这扩展工具和Sizzle之间的一块,

到时候讲到这儿的时候再来给大家详细的来说。


    // Support: IE9

    // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`

    core_strundefined = typeof undefined,

下边这一段,先看这句typeof undefined,

它得到的是字符串的undefined,

所以说这个变量存的就是一个字符串形式的undefined,

那它为什么会这么做?

上边也给了解释,我们先不看这个解释,

先来看看用typeof去判断还是直接用undefined有什么不同,

// 比如看window下的a是否存在

window.a == undefined;

// 或者用typeof

typeof window.a == 'undefined';

其实这两种写法都可以判断window下的这个属性是否存在,

但是非常少的情况下,光用上面的那种判断是不行的,

什么情况下不能呢?

就是上班注释上面写的,这个支持IE9,

其实呢,在IE老版本当中包括IE6,7,8都会有这个问题,

只不过,这个2.0的版本不考虑IE6,7,8,

在老版本的浏览器下假如我们去判断的是xmlnode的方法或属性,

这个时候光用上面的那种形式去判断,它可能判断不出来,

判断的证据不充分,所以要做到所有兼容需要用第二种方法,

它是全部兼容的,这种出现问题的情况非常少,

在这个xml的情况下才会有问题,本来我们用xml的时候又不多,

所以说这是小众情况下有这样一个bug。

像这个问题我们也可以用bugs去搜索,

虽然没有索引号,但是依然能够搜索,

可以看到一些它的详细的描述。

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



回看上一集:


别走开,下集更精彩。

喜欢文章的小伙伴,

希望大家多多转发分享,

你的分享就是我的动力!

喜欢
分享
or

以上是关于[No.4] jQuery源码解析—逐段解析的主要内容,如果未能解决你的问题,请参考以下文章

[No.6 jQuery源码解析—逐段解析

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

jQuery 源码解析一:jQuery 类库整体架构设计解析

jQuery公司源码解析

JQuery源码解析-JQuery的工具方法

jQuery源码解析--结构分析