jQuery是怎样工作的

tsl0922 发布于 2012/08/08 11:39
阅读 2K+
收藏 18
介绍
jQuery是时下最为流行的JavaScript库。它使用CSS选择器样式语法获取文档对象模型(DOM)中的元素到已包装的对象集合中,然后使用jQuery方法操纵这些元素来达到不同的效果。尽管jQuery的使用是非常方便和直观的,我们还是需要弄懂它背后的机制来更好的掌握它。

jQuery中的基本概念
在我们深入研究jQuery库前,需要了解一些jQuery中的一些基本概念。

$/jQuery对象和$()/jQuery()方法
$/jQuery对象是一个全局对象,通过它来访问所有的jQuery方法。

它也是一个方法对象,所以使用它最通常的方法是通过$/jQuery()方法。$/jQuery()方法可以用来选择DOM中的一组元素。它也是一个包装函数,一个$/jQuery()方法的简单例子:
$(“#ABC”); 
or 
jQuery(“#ABC”);

传给$/jQuery()方法的参数是选择器( selector)。选择器是一个有CSS选择器样式语法的表达式。在上面的例子中,我要选择id等于 #ABC 的元素

包装集合(Wrapped set)
包装集合是一个类似数组的结构,里面包含了所有已选择的DOM元素。上面的$("#ABC")返回了一个包装集合。你可以像遍历数组那样访问包装集合或者通过索引访问。更重要的是,你可以在所有被选择的元素上应用jQuery方法。

jQuery $()/jQuery()方法在后台是怎么工作的
因为大多数jQuery方法调用都是以$()/jQuery()开头的,所以我们有必要弄懂在这后面发生了什么。在深入讨论前,我们先看看$()/jQuery()对象是在哪定义的。$/jQuery对象是jQuery方法的访问点,是在jQuery中定义的一个全局方法变量。这是在jQuery源码中定义它的那一行:
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;

window对象代表浏览器中打开的窗口,把$/jQuery放到window下,它就得定义为一个全局对象并且可以在当前打开的窗口中访问

但是,上面一行源码最的"jQuery"是什么?它被声明在jQuery库开始的地方。
var jQuery = (function() {
…

这所有的魔法都发生在jQuery对象的声明表达式中,如果你直接往里面看,可能会迷茫,所以让我来简化它吧。

简化版jQuery库源代码
警告:简化版本仅仅为了研究目的,它不并具有jQuery提供的所有功能,不要把它用在真实环境中。
var jQuery = (function ()
{
	// Define a local copy of “k”
	var k = function (selector, context)
	{
		// The k object is actually just the init constructor 'enhanced'
		var kobj = new k.fn.init(selector, context);
		return kobj;
	};

	//Define k’s fn prototype, specially contains init method
	k.fn = k.prototype = {
		init: function (selector, context)
		{
			if (!selector)
			{
				return this;
			}
		}
	};

	// Give the init function the “k” prototype for later instantiation
	k.fn.init.prototype = k.fn;

	// Return “k” to the global object
	return k;
})();

从上面的额源码你可以看到jQuery函数变量被定义为一个匿名方法的执行结果。
小贴士:怎样定义匿名函数 在Javascript中你可以定义一个匿名函数并马上调用它 例如, (function () { alert(“hello world”); })(); 通过把函数表达式 function() { alert(“hello word”); } 放进括号中 (function() { alert(“hello world”); }) 你可以在外面再加个括号马上调用它
在这个匿名函数内部定义了一个函数,它有这样的形式:
function (selector, context)

第一个参数是selector,第二个参数是context。在原始的jQuery源码中,函数k实际上被命名为jQuery,这会和外面大多数jQuery函数变量混淆。

在函数k内一个匿名函数类定义为k的prototype,Prototype是JavaScript函数类的一个特殊的,被用来指向另一个函数对象。所以,所有那个函数类的实例都可以访问在prototype函数类中定义的函数。在这里,init函数可以被函数类k的所有实例访问。init方法有如下的形式:
function (selector, context)

k的prototype里已经初始化成员方法,与此同时,init函数的prototype又被赋值为k的prototype。这是一个循环引用,正常编程实践中应该避免。但是,jQuery就是采用这种方式使init函数的返回值可以访问k中定义的方法。
小贴士:在JavaScript中函数是实体类 Javascript是函数式编程语言,但是函数并不是传统中那样纯粹的函数。函数可以动态定义,可以拥有属性和方法,并且可以作为参数传递给另一个函数。如果你想以传统的方式执行函数,可以这样: function display() { alert(“hello world”); } display(); 如果你想把函数当做类使用,可以这样: function Car(model) { this.Model = model; this.Drive = function() { alert(“Go”) } } var car = new Car(“Ford”); 在这里,function实际上是用来定义一个Car“类”,Car类有一个可以用函数类的参数初始化的属性Model和方Drive方法。所以,你可以随便创建任意多个Car类的对象。然而,JavaScript的类并不是真正的类,因为它并没有面向对象语言中类的三个主要特征。
定义k的prototype函数的方法被称作function literal,这在jQuery中广泛使用。
小贴士:JavaScript中定义方法的各种方式 1.使用function statement: function open() { //open logic } 2.使用function literal你可以用下面的方式定义最简单的函数: var o = { } 你还可以用literal定义一个函数“类”: var apple = { type: “macintosh”, color: “red”, getInfo: function() { return this.color + ‘ ‘ + this.type + ‘ apple’; } } 3.使用Function对象定义函数 Function对象是JavaScript中内建的对象,在JavaScript中,可以这样 var add = new Function(a, b, “return a + b;”); 来定义一个函数“add”。Function会把开始的两个参数“a”和"b"当做函数的参数,最后一个参数“return a + b”当做函数体。
这样,内部的函数k就返回给了外部变量jQuery。jQuery得到的不仅是函数k,而且还有函数k所在的闭包(closure)。
小贴士:JavaScript中的closure是什么? closure是把内部函数返回到外部时JavaScript创建的一个上下文(context),所以内部的函数还是可以访问那些本地变量。 closure的一个例子: var addition = function(numberA) { return function(numberB) { alert (numberA + numberB); }} 这样,你就可以直接指定numberA的值来创建一个addition的实例。 var add2 = addition(2); var add3 = addition(3); add2(3); // it will display 5 add3(3); // it will display 6
最后,函数k被返回到了全局jQuery函数那里。

jQuery函数库错综复杂的设计是为了使扩展和使用这个库简单容易。你可以附加自定义函数到jQuery.fn来添加你自己的业务逻辑。这个自定义的函数可以像内置函数那样被调用,比如:
// Define a plugin function Test
jQuery.fn.Test = function () { alert("Test"); }

// Invoke Test function via jQuery() function
jQuery().Test();

总结
通过了解jQuery是如何工作的,我们可以更好地掌握这个JavaScript库。 我在这篇文章中显示的仅仅是jQuery库的框架。在掌握了基本的设计原则和jQuery库机制后,你可以深入研究jQuery库的原始源代码来更多的了解jQuery如何发挥JavaScript语言的优势,实现简单和可扩展性的目标。

加载中
0
jeffsui
jeffsui
呃,最近在看mootools,很多实现原理和jquery相似。
0
返回顶部
顶部