jQuery的运行机制和设计理念分析

2020-05-19 07:43:28易采站长站整理

通过jQuery(xxx)的调用实现没有生成对象,它的this是指向Window对象的。那么jQuery的那些实例方法是怎样继承过来的呢?看一下:
var jQuery = window.jQuery = window.$ = function(selector, context)
{ return new jQuery.fn.init(selector, context);
};
这是jQuery的总的入口,jQuery对象实际上不是通过new jQuery()而继承其prototype的中的方法。jQuery对象实际是jQuery.fn.init函数生成的对象。在里我们可以看出对于 jQuery.prototype添加一些函数集的对象的意义不大。因为我们new jQuery()是可以的,但是生成的jQuery对象在return时会被抛弃。所以最好不要用new jQuery()来构建jQuery对象。jQuery对象其实就是new jQuery.fn.init。那么jQuery.fn.init.prototype上就是挂着jQuery对象的操作方法。如
jQueryjQuery.fn.init.prototype = jQuery.fn;
有时间可能会担心在589行就实现了把jQuery.fn中的函数放到jQuery.fn.init.prototype上去,那么之后的通过 jQuery.fn.extend的方法怎么办呢?这里实际是对jQuery.fn的引用。在扩展jQuery的时候,只要把相关的函数extend到 jQuery.fn就可以了。现在我们看一下jQuery.fn.init是怎么完成工作的:

init : function(selector, context) {
selectorselector = selector || document;// 确定selector存在
// 第一种情况 Handle $(DOMElement)单个Dom 元素,忽略上下文
if (selector.nodeType) {
this[0] = selector;
this.length = 1;
return this;
}
if (typeof selector == “string”) {//selector为string
var match = quickExpr.exec(selector);
if (match && (match[1] || !context)) {
if (match[1])// 第二种情况处理$(html) -> $(array)
selector = jQuery.clean([match[1]], context);
else {// 第三种情况:HANDLE: $(“#id”)//处理$(“#id”)
var elem = document.getElementById(match[3]);
if (elem) {
// IE会返回name=id的元素 ,如果是这样,就document.find(s)
if (elem.id != match[3])
return jQuery().find(selector);
// 构建一个新的jQuery(elem)
return jQuery(elem);
}
selector = [];
}
} else
// 第四种情况:处理$(expr, [context])==$(content).find(expr)
return jQuery(context).find(selector);
} else if (jQuery.isFunction(selector)) // 第五种情况:处理$(function)七Shortcut for document ready
return jQuery(document)[jQuery.fn.ready ? “ready” : “load”](selector);
// 第六种情况:处理$(elements)
return this.setArray(jQuery.makeArray(selector));
}