jquery源码学习1

jQuery整体架构

任何程序代码不是一开始就复杂的,成功也不是一躇而蹴的,早期jQuery的作者John Resig在2005年提议改进Prototype的“Behaviour”库时,只是想让其使用更简单才发布新的jQuery框架。起初John Resig估计也没料想jQuery会如此的火热。我们可以看到从发布的第一个1.0开始到目前最新的2.1.1其代码膨胀到了9000多行,它兼容CSS3,还兼容各种浏览器,jQuery使用户能更方便地处理DOM、事件、实现动画效果,并且方便地为网站提供AJAX交互。

1、最新jQuery2.1.1版本的结构:
代码请查看右侧代码编辑器(1-24行)

2、jQuery的模块依赖网:
 jquery源码学习1_第1张图片

(单击图片可放大)

jQuery一共13个模块,从2.1版开始jQuery支持通过AMD模块划分,jQuery在最开始发布的1.0版本是很简单的,只有CSS选择符事件处理AJAX交互3大块。其发展过程中,有几次重要的变革:

    ☑  1.2.3 版发布,引入数据缓存,解决循环引用与大数据保存的问题
    ☑  1.3 版发布,它使用了全新的选择符引擎Sizzle,在各个浏览器下全面超越其他同类型JavaScript框架的查询速度,程序库的性能也因此有了极大提升
    ☑  1.5 版发布,新增延缓对像(Deferred Objects),并用deferred重写了Ajax模块
    ☑  1.7 版发布,抽象出回调对象,提供了强大的的方式来管理回调函数列表。

每一次大的改进都引入了一些新的机制、新的特性,通过这些新的机制就造就了如今jQuery库,一共13个模块,模块不是单一的,比如jQuery动画,都会依赖异步队列、动画队列、回调队列与数据缓存模块等。

jQuery抽出了所有可复用的特性,分离出单一模块,通过组合的用法,不管在设计思路与实现手法上jQuery都是非常高明的。

五大块:
jQuery按我的理解分为五大块,选择器DOM操作事件AJAX与动画,那么为什么有13个模块?因为jQuery的设计中最喜欢的做的一件事,就是抽出共同的特性使之“模块化”,当然也是更贴近S.O.L.I.D五大原则的“单一职责SRP”了,遵守单一职责的好处是可以让我们很容易地来维护这个对象,比如,当一个对象封装了很多职责的时候,一旦一个职责需要修改,势必会影响该对象的其它职责代码。通过解耦可以让每个职责更加有弹性地变化。
我们来看看jQuery文档针对业务层的Ajax的处理提供了一系列的门面接口:

.ajaxComplete()
.ajaxError()
.ajaxSend()
.ajaxStart()
.ajaxStop()
.ajaxSuccess()

底层接口:

jQuery.ajax()
jQuery.ajaxSetup()

快捷方法:

jQuery.get()
jQuery.getJSON()
jQuery.getScript()
jQuery.post()

 

jQuery接口的设计原理

业务逻辑是复杂多变的,jQuery的高层API数量非常多,而且也非常的细致,这样做可以更友好的便于开发者的操作,不需要必须在一个接口上重载太多的动作。我们在深入内部看看Ajax的高层方法其实都是统一调用了一个静态的jQuery.ajax方法,代码见右侧代码编辑器(27-43行)
jQuery.ajax的内部实现是非常复杂的,首先ajax要考虑异步的处理与回调的统一性,所以就引入了异步队列模块(Deferred)与回调模块(Callbacks), 所以要把这些模块方法在ajax方法内部再次封装成、构建出一个新的jQXHR对象,针对参数的默认处理,数据传输的格式化等等。

源码核心代码:

<script type="text/javascript">
;(function(global, factory) {
    factory(global);
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
    var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
};
jQuery.fn = jQuery.prototype = {};
// 核心方法
// 回调系统
// 异步队列
// 数据缓存
// 队列操作
// 选择器引
// 属性操作
// 节点遍历
// 文档处理
// 样式操作
// 属性操作
// 事件体系
// AJAX交互
// 动画引擎
return jQuery;
}));




jQuery.each( [ "get", "post" ], function( i, method ) {
    jQuery[ method ] = function( url, data, callback, type ) {
// Shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
type     = type || callback;
callback = data;
data     = undefined;
}
return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
});
};
});


</script>


附录:$.fn

$.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效。 
如扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后面你的每一个jquery实例都可以引用这个方法了. 
那么你可以这样子:$("#div").abc(); 

jQuery为开发插件提拱了两个方法,分别是: 

jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法。 
jQuery.fn.extend(object);给jQuery对象添加方法。 

fn是什么东西呢。查看jQuery代码,就不难发现。 

复制代码代码如下:

jQuery.fn = jQuery.prototype ={ 
   init: function( selector, context ){//....  
   //...... 
}; 

原来 jQuery.fn =jQuery.prototype.对prototype肯定不会陌生啦。 
jQuery便是一个封装得非常好的类,比如我们用语句 $("#btn1") 会生成一个 jQuery类的实例。 

jQuery.extend(object); 为jQuery类添加添加类方法,可以理解为添加静态方法。如: 
复制代码代码如下:

$.extend({ 
  add:function(a,b){returna+b;} 
}); 

便为 jQuery 添加一个为add 的 “静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了, 
$.add(3,4); //return 7 

jQuery.fn.extend(object);对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。 
比如我们要开发一个插件,做一个特殊的编辑框,当它被点击时,便alert当前编辑框里的内容。可以这么做: 

jQuery代码 
复制代码代码如下:

$.fn.extend({ 

alertWhileClick:function(){ 

$(this).click(function(){ 

alert($(this).val()); 
}); 

}); 

你可能感兴趣的:(jquery源码)