1. jQuery代码的机制; ——表现形式或者是使用方法
2. jQuery原理的函数实现过程; ——代码实现
1. 要有相关javascript的基础知识,例如:闭包作用域、promise异步、原型等等;
2. 相关DOM操作的基础知识;
3. 会正则表达式;
源码下载步骤:
1. 进入jQuery官网:www.jQuery.com ;
2. 点击 Download进入下载页;
3. 有一下两个版本(注:这边的版本可能落后于现在的版本了,因为作者学习的视屏中的版本是很早之前的版本,所以这边提供了之前版本的下载地址,并且本套笔记中均使用 jQuery 2.0.3 进行配套讲解)
(1) jQuery 1.10.2
(2) jQuery 2.0.3
jQuery从2.x版本开始就不再支持IE6、IE7和IE8的浏览器版本了。对应的只支持比较高级的浏览器版本。
↓
这样做的好处:
可以减少一些兼容性的写法,减少hack的写法的代码
↓
所以我们下面文档的讲解均以 jQuery 2.0.3为参考进行讲解。
使用Microsoft Visual Studio 2015对 jQuery 2.0.3.js 打开(当然也可以使用DreamWare或者是WebStorm等的软件进行打开,博主比较喜欢用vs来写),这里不使用jQuery的min版本,因为min版本e中有变量的简写以及不存在换行,不便于用作学习。
打开后可以看到一共有8830行的代码。如下图所示:
我们先整理 jQuery的整体框架(简化框架)
如下图所示:
(function( window, undefined ) {
//jQuery内核代码
})( window );
<1>对于第14行开始的“ function( window, undefined ){ ”是一个匿名数,而对于在8829行的“ })(window)”则是对14行这个匿名函数的“自执行”调用;
※那么,这样写有什么好处吗?
学过函数作用域的都应该知道函数的作用域。在匿名函数里面写的东西都会是局部的,在外面无法访问,防止了定义的变量和函数对外部空间的“污染”,体现了面向对象的原则。
例如:
(function(){
var a=10;
function $()
{
alert(a);
};
})();
alert(a);//定义的变量a无法再外部使用
$(); //定义的函数也没有办法在外部使用
在上面的代码中
对于“ alert(a); ”和“ $(); ”的执行结果分别为 “ ‘a’ is undefined !” 和“ ‘$’ is undefined function!”;
※那么如何才能在外部代码中可以访问匿名函数中的变量和函数呢?
其实,有很多的方法是可以做到的。例如把你需要调用的变量和函数挂载到window对象上,例如如下代码:
( function() {
var a=10;
function $()
{
alert(a);
};
window.$=$;
})();
$(); //调用会弹出alert弹窗并显示10
或者
( function(widowObj) { //为了体现是传递参数,这边就写成windowObj
var a=10;
function $()
{
alert(a);
};
widowObj.$=$;
})(window);
$(); //调用会弹出alert弹窗并显示10
在jQuery中是按照上面给出的第二种进行传参挂载的。
首先我们要先了解一下:
jQuery=function(...){...}
【1】我们平时使用的" $ "或者“ jQuery ”都是上面的声明的变量;
【2】那么我们为什么可以访问到它呢?
答:和前面的匿名自执行一样。他把内部的" $ "或者“ jQuery ”在传入的window对象上进行挂载。
if ( typeof window === "object" && typeof window.document === "object" ) {
window.jQuery = window.$ = jQuery;
}
这里便是将" $ "和" jQuery "进行挂载。首先,它先判断了一下,传入的window是不是一个有document文档节点的对象。这边由于我们网页中的window对象中自带document对象,所以做这样的判断。
jQuery.fn = jQuery.prototype = {...}
上面的代码" jQuery.prototype "是 jQuery对象的原型,它是一个面向对象的概念,所以 jQuery是一个基于面向对象(Object Oriented)的语言。
※从使用的角度看,为什么 jQuery是一个面向对象的语言?
首先我们看一下普通的面向对象:
对于一个数组对象
var arr = new Array();
arr.push();
arr.sort();
上面可以看到push和sort方法之所以可以调用,是因为arr是一个数组的对象,对象中有定义的对应的方法来控制和处理对象。
那么,类似的,我们看一下 jQuery对象
$('#div').css('background-color','red');
$('#div').html('这是一个div');
上面的css和html方法之所以可以调用,是因为" $('#div') "的执行结果是返回一个 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中由于挂载的定义我们可以知道" $(...) "等价于" jQuery(...) ",只是我们平时为了书写方便,所以多用" $ "符号的形式。对于jQuery的定义我们可以看到,它其实是一个函数的标识符,它代表的是一个函数对象。那么执行" $(...) "其实是在执行一个函数方法。在看到对于这个匿名函数,它有一个返回值" return new jQuery.fn.init( selector, context, rootjQuery ) ",它是一个用new关键字调用构造函数返回对象的过程,从此也可以知道 jQuery是一门面向对象的语言。
jQuery.extend = jQuery.fn.extend = function() {...}
上面的代码,其实是定义了jQuery的继承方法。
目的:jQuery的开发者希望后续添加的代码,都可以通过extend挂载到 jQuery对象中,这样做可以比较方便的进行扩展,而不是一上来就把所有的方法写到一起,而不利于代码的后期的独立性、扩展性和可维护性。即,继承可以方便后期的插件扩展。
jQuery.extend({
...
});
首先,这里用的就是上面对继承方法的定义的使用。它定义了一些工具方法。
★★★下面我们要理清一些基本的概念 ★★★:
<1> jQuery中提供了两种操作代码的方式:
操作代码的方式 | 操作类型 | 所属方法类型 | 例子 |
方式一 | 使用选择器 | 对象,对象方法(); | $('#div').html(); 也可以写作为 jQuery('#div').html(); |
方式二 | 直接使用 jQuery对象 | 静态方法();(纯函数的方法) | $.trim(); $.proxy(); 也可以写作 jQuery.trim(); jQuery.proxy(); |
在 jQuery中,来给面向对象进行扩展静态属性和静态方法的过程,我们称之为"扩展工具方法"。
<2> jQuery的对象方法与扩展工具方法的区别:
【1】扩展的工具方法,它既可以给 jQuery对象来使用,有可以给原生的javaScript的代码来进行使用;
【2】而像css和html这类的 jQuery对象方法,只能给 jQuery对象来使用;
<3>扩展这些工具方法是为了便于 jQuery自身或者是用户在后期可以使用,使得一些处理过程进行简化、复用。
※那么静态方法和对象方法之间的关系究竟是什么呢?
如下图:
代码所在的程序行数 | 对应的代码段的功能梗概 |
0~20 | ( function (){ |
21~94 | 定义了一些变量和函数,重点:jQuery=function(...){...} |
96~283 | 给jQuery对象添加一些方法和属性 |
285~347 | extend:jQuery的继承方法 |
349~817 | jQuery.extend():扩展一些工具方法 |
... | ... |
8826 | window.jQuery=window.$=jQuery:jQuery对象挂载 |
最后 | })(); |