对于大多数人来说它就像一个magic black box,但jQuery是如何工作的,可能研究的人就不多了。本文稍微谈一下,jQuery源码,以及它的工作原理。
jQuery的源码host在github.com上,现在正在处于1.5向1.6的开发阶段。将master branch拉下来make一下,就可以在dist目录下看到jquery.js了。或者如果你更愿意看分模块的code,就直接到src下看。
Overview
打开jquery.js,它的基本结构是这样的:
// This is an self-executing anonymous function (function(window, undefined) { var jQuery = (function() { var jQuery = function(selector, context) { return new jQuery.fn.init(selector, context, rootjQuery); }, rootjQuery; jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function(selector, context, rootJQuery) { // ... return this; } // ... }; jQuery.fn.init.prototype = jQuery.fn; return jQuery; })(); // ... window.jQuery = window.$ = jQuery; })(window); // alert($());
Self-executing anonymous function
最外层是一个自执行的匿名函数(self-executing anonymous function)。它有两个作用:
- 作为一个匿名的namespace。在函数内部的变量不再是全局变量,不会影响到其他库和用户代码,也不会受它们的影响。
- 防止恶意程序改写undefined(javascript允许重新定义这个关键字,evil feature),一个简单的例子如下。jQuery定义了一个两个参数的函数,调用的时候只传一个。保证了函数中的undefined一定是“真的”undefined。
函数内部第3行定义了一个内部对象jQuery,第25行将这个对象export到global space,赋值给window.$和window.jQuery。然后$("#id")就可以work了。
第3-21行又定义了一个自执行的匿名函数,作用一样,是一个namespace,在jQuery不同模块之间做隔离。第4行再次定义了一个jQuery,在第20行返回了这个jQuery。这个jQuery就是最终用户得到的对象(函数也可以认为是对象)。
What jQuery is?
这个jQuery是个什么呢?
它是一个function(同时又是一个constructor function和object),所以以下三种用法都是可以的。
可以看到作为function和constructor function它的意义是一样的,它会返回一个jQuery.fn.init的对象。
jQuery.fn.init在第12行定义,它做的事情就是parse输入的selector和context,返回jQuery对象。这个名字比较绕,其实可以把jQuery.fn.init看作一个整体就好理解多了。第9-18行其实可以理解成下面一行代码。不管你的object是new $("#id")还是$("#id"),对它们调用的方法会落到这个prototype中。
(jQuery.fn.init).prototype = jQuery.fn = jQuery.prototype = { //... };
Extending jQuery
因此如果要在上述object上扩展一个方法,很简单
// The following notations are OK as well: // $.fn.init.prototype.new_func // $.prototype.new_func $.fn.new_func = function() { // ... }
当然jQuery提供了专门的方法($.fn.extend)做这件事情。
另外我们还看到$.browser这样的方法。要扩展这样的方法同样很简单
$.new_func() = function() { // ... }
同样,jQuery提供了专门的方法($.extend)做这件事情。
这里大家也发现了,jQuery有两类方法,$("").xxx和$.xxx。在jQuery的官方文档上它也是加以区分的,
- .add()表示前者;
- jQuery.ajax()表示后者
一些比较好的资源:
- 一个jQuery代码浏览器
- 又一个jQuery代码浏览器
- jQuery Fundemental,其实是讲了javascript和jQuery两个东西的基础
- Paul Irish,一个jQuery的开发者
- 最好的地方,the Source
没有评论:
发表评论