[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,
然后,把这个索引放到输入框内,
进行搜索,
然后我们就可以看到跟这一块有关,
更加具体的说明,
下边还有很多人留言和讨论,
都可以查看得到。
再下来我们看到一行,
在之前跟大家讲过,
这个匿名函数自执行,
(function( window, undefined ) {
它的一个作用是里面的代码都是局部的,
然后呢,跟外边的代码不冲突,
就是这样一个作用,
那我们老看一下,
它为什么要把window当参数,
传到这个闭包当中,
<script>
// 在jQuery中一上来就是一个匿名函数自执行
(function(window){
// 先传了一个window
// })(window);
// 如果不传这个window
// 我们直接在这个里面使用window其实也是可以的
window
// 那它为什么还要去传呢?
// 有两点
// 第一点:window是我们js的最顶端,它的查找速度比较慢
// 根据这个作用域面的原理,变量是找离它最近定义那个变量开始查找
// 如果找不到的话,它才会一层一层往外找
// 所以说在你传参之后,它找是里面的这个window,不会去找外边的window
// 它的查找速度更快
// })()
// 第二点:这个window传过来之后,对于压缩版本就很有用的
// 如果是不传window它是压缩不了的,
})(window)
</script>
然后我们打开这个压缩版本,
可以看到,传过来的就不是window了,
而是e了,是吧!
所以下边用到e的都是window,
对于,压缩来说的特方便的,
这就是它为什么要传window,
对于查找和压缩都有好处。
其实在下边很多变量都是跟这个有关的,
咱们到时候读到的时候,再给大家去讲。
接着,看这个undefined,它也是传过来的,
它没有被压缩,为什么要传它呢?
首先,我们来了解一下这个undefined属性,
它既不是保留字,也不是关键字,
这个undefined在外边是可以被修改的,
// 比如我定义了一个undefined等于十
var undefined = 10;
// 然后我打印一下
console.log(undefined);
在IE10下,它是undefined,
在IE8下是10,
所以说在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,咱们这节暂时讲到这里!
回看上一集:
别走开,下集更精彩。
喜欢文章的小伙伴,
希望大家多多转发分享,
你的分享就是我的动力!
以上是关于[No.4] jQuery源码解析—逐段解析的主要内容,如果未能解决你的问题,请参考以下文章