jQuery技术

浅析jQuery整体框架与实现(上)

字号+ 作者:H5之家 来源:H5之家 2016-09-03 12:00 我要评论( )

jquery中文网为您提供浅析jQuery整体框架与实现(上)等资源,欢迎您收藏本站,我们将为您提供最新的浅析jQuery整体框架与实现(上)资源

前言

jquery整体框架甚是复杂,也不易读懂,这几日一直在研究这个笨重而强大的框架。jQuery的总体架构可以分为:入口模块、底层模块和功能模块。这里,我们以jquery-1.7.1为例进行分析。

jquery的总体架构 16 (function( window, undefined ) { // 构造 jQuery 对象 22 var jQuery = (function() { 25 var jQuery = function( selector, context ) { 27 return new jQuery.fn.init( selector, context, rootjQuery ); 28 }, // 一堆局部变量声明 97 jQuery.fn = jQuery.prototype = { 98 constructor: jQuery, 99 init: function( selector, context, rootjQuery ) { ... }, // 一堆原型属性和方法 319 }; 322 jQuery.fn.init.prototype = jQuery.fn; 324 jQuery.extend = jQuery.fn.extend = function() { ... }; 388 jQuery.extend({ // 一堆静态属性和方法 892 }); 955 return jQuery; 957 })(); // 省略其他模块的代码 ... 9246 window.jQuery = window.$ = jQuery; 9266 })( window );

分析一下以上代码,我们发现jquery采取了匿名函数自执行的写法,这样做的好处就是可以有效的防止命名空间与变量污染的问题。缩写一下以上代码就是:

(function(window, undefined) { var jQuery = function() {} // ... window.jQuery = window.$ = jQuery; })(window); 参数window

匿名函数传了两个参数进来,一个是window,一个是undefined。我们知道,在js中变量是有作用域链的,这两个变量的传入就会变成匿名函数的局部变量,访问起来的时候速度会更快。通过传入window对象可以使window对象作为局部变量使用,那么,函数的参数也都变成了局部变量,当在jquery中访问window对象时,就不需要将作用域链退回到顶层作用域,从而可以更快的访问window对象。

参数undefined

js在查找变量的时候,js引擎首先会在函数自身的作用域中查找这个变量,如果没有的话就继续往上找,找到了就返回该变量,找不到就返回undefined。undefined是window对象的一个属性,通过传入undefined参数,但又不进行赋值,可以缩短查找undefined时的作用域链。在 自调用匿名函数 的作用域内,确保undefined是真的未定义。因为undefined能够被重写,赋予新的值。

jquery.fn是啥? jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { ... }, // 一堆原型属性和方法 };

通过分析以上代码,我们发现jQuery.fn即是jQuery.prototype,这样写的好处就是更加简短吧。之后,我们又看到jquery为了简洁,干脆使用一个$符号来代替jquery使用,因此,在我们使用jquery框架的使用经常都会用到$(),

构造函数jQuery()

浅析jQuery整体框架与实现(上)

jQuery的对象并不是通过 new jQuery 创建的,而是通过 new jQuery.fn.init 创建的:

var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }

这里定义了一个变量jQuery,他的值是jQuery构造函数,在955行(最上面的代码)返回并赋值给jQuery变量

jQuery.fn.init

jQuery.fn (上面97行)是构造函数jQuery()的原型对象,jQuery.fn.init()是jQuery原型方法,也可以称作构造函数。负责解析参数selector和context的类型并执行相应的查找。

参数context:可以不传入,或者传入jQuery对象,DOM元素,普通js对象之一
参数rootjQuery:包含了document对象的jQuery对象,用于document.getElementById()查找失败等情况。

jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype

jQuery(selector [,context])

默认情况下,对匹配元素的查找从根元素document 对象开始,即查找范围是整个文档树,不过也可以传入第二个参数context来限定它的查找范围。例如:

$('div.foo').click(function () { $('span',this).addClass('bar');//限定查找范围,即上面的context }); $.extend()和$.fn.extend()

方法jQuery.extend(object)和jQuery.fn.extend(object)用于合并两个或多个对象到第一个对象。相关源代码如下(部分):

jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone,//定义的一组局部变量 target = arguments[0] || {}, i = 1, length = arguments.length, deep = false;

相关变量含义如下:

变量options:指向某个源对象 变量name:表示目标对象的某个属性名 变量src:表示目标对象的某个属性的原始值 变量copy:表示某个源对象的某个属性的值 变量copyIsArray:指示变量copy是否是数组 变量clone:表示深度复制时原始值的修正值 变量target:指向目标对象 变量i:表示源对象的起始下标 变量length:表示参数的个数,用于修正变量 变量deep:指示是否执行深度复制,默认为false

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

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

便为 jQuery 添加一个为add 的 “静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了, 就是将add方法合并到jquery的全局对象中。

$.add(3,4); //return 7

jQuery.fn.extend(object),查看一段官网的代码演示如下:

<label><input type="checkbox"> Foo</label> <label><input type="checkbox"> Bar</label> <script> jQuery.fn.extend({ check: function() { return this.each(function() { this.checked = true; }); }, uncheck: function() { return this.each(function() { this.checked = false; }); } }); // Use the newly created .check() method $( "input[type='checkbox']" ).check(); </script>

看下面一个jQuery对象的扩展方法:

$.fn.extend({ sayHello : function(){ alert('hello'); } });

就是将sayHello方法合并到jquery的实例对象中

CSS选择器引擎 Sizzle

可以说,jQuery是为操作DOM而诞生的,jQuery之所以如此强大,得益于CSS选择器引擎 Sizzle,解析规则引用网上的一段实例:

selector:"div > p + div.aaron input[type="checkbox"]" 解析规则: 1 按照从右到左 2 取出最后一个token 比如[type="checkbox"] { matches : Array[3] type : "ATTR" value : "[type=" checkbox "]" } 3 过滤类型 如果type是 > + ~ 空 四种关系选择器中的一种,则跳过,在继续过滤 4 直到匹配到为 ID,CLASS,TAG 中一种 , 因为这样才能通过浏览器的接口索取 5 此时seed种子合集中就有值了,这样把刷选的条件给缩的很小了 6 如果匹配的seed的合集有多个就需要进一步的过滤了,修正选择器 selector: "div > p + div.aaron [type="checkbox"]" 7 OK,跳到一下阶段的编译函数 deferred对象

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。

简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是”延迟”,所以deferred对象的含义就是”延迟”到未来某个点再执行。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
网友点评
t