jQuery源码分析(一)
我们知道在jQuery中在使用选择器或者给元素绑定事件的时候都是通过$来操作的。那么基于JavaScript面向对象的思想,我们可以把jQuery看做一个函数或者对象,它里边存储了大量的方法,是一个类库。
$代表的就是jQuery
$.ajax() --------- jQuery.ajax() 当做对象来看就是jQuery调用它静态私有的属性和方法,同样我们可以再控制台输出一下dir(jQuery)看到jQuery对象中存储属性和方法:
jQuery.prototype 原型上存储的就是供jQuery实例对象调用的方法。同样输出一下jQuery.prototype
$(’.box’).addClass()就是找的jQuery.prototype中的addClass方法那么我们就可以把
$(’.box’)看作是jQuery的一个实例对象,原型上的属性和方法只能被其所属类或所属类的实例调用。上源码
varversion = "3.5.1",//这是在$也就是jQuery执行的时候做的操作 jQuery = function jQuery(selector, context) {// selector:选择器类型 「字符串(选择器/HTML字符串)、函数、DOM元素对象...」// context:上下文,限制其获取的范围return new jQuery.fn.init(selector, context);};
// 原型方法:供实例调用 原型重定向
jQuery.fn = jQuery.prototype = {jquery: version,constructor: jQuery,// ...
};
//这两段代码意思是一样的
var jQuery.fn = jQuery.prototype;jQuery.prototype={jquery: version,constructor: jQuery};
上边这段代码表示:原型重定向以后会丢失之前的属性和方法,所以jQuery中自己给新原型加上了jquery和constructor属性。那么在jQuery执行的时候new jQuery.fn.init(selector, context)就是调用的new jQuery.prototype.init(selector, context))也就是原型上的init方法
var rootjQuery = jQuery(document),rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,init = jQuery.fn.init = function (selector, context, root) {var match, elem;// HANDLE: $(""), $(null), $(undefined), $(false)if (!selector) {return this;}// Method init() accepts an alternate rootjQuery// so migrate can support jQuery.sub (gh-2101)root = root || rootjQuery;// Handle HTML stringsif (typeof selector === "string") {if (selector[0] === "<" &&selector[selector.length - 1] === ">" &&selector.length >= 3) {// Assume that strings that start and end with <> are HTML and skip the regex checkmatch = [null, selector, null];} else {match = rquickExpr.exec(selector);}// Match html or make sure no context is specified for #idif (match && (match[1] || !context)) {// HANDLE: $(html) -> $(array)if (match[1]) {context = context instanceof jQuery ? context[0] : context;// Option to run scripts is true for back-compat// Intentionally let the error be thrown if parseHTML is not presentjQuery.merge(this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,true));// HANDLE: $(html, props)if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {for (match in context) {// Properties of context are called as methods if possibleif (isFunction(this[match])) {this[match](context[match]);// ...and otherwise set as attributes} else {this.attr(match, context[match]);}}}return this;// HANDLE: $(#id)} else {elem = document.getElementById(match[2]);if (elem) {// Inject the element directly into the jQuery objectthis[0] = elem;this.length = 1;}return this;}// HANDLE: $(expr, $(...))} else if (!context || context.jquery) {return (context || root).find(selector);// HANDLE: $(expr, context)// (which is just equivalent to: $(context).find(expr)} else {return this.constructor(context).find(selector);}// HANDLE: $(DOMElement)} else if (selector.nodeType) {this[0] = selector;this.length = 1;return this;// HANDLE: $(function)// Shortcut for document ready} else if (isFunction(selector)) {return root.ready !== undefined ?root.ready(selector) :// Execute immediately if ready is not presentselector(jQuery);}return jQuery.makeArray(selector, this);};//init的原型指向重定向以后的原型
init.prototype = jQuery.fn;
基于原型和原型链的图:














![[转]2d游戏开发:游戏地图编辑器](http://image.jqcq.com/upload/2006-06/15/11503525054.png)

