总体架构
jQuery是个出的javascript库,最近结合它写javascript,看了下源码。
先从整体、全局的看,jQuery的源码几乎都在下面的代码中:
(function() {
//……
})();
//……
})();
第一个括号里面是个匿名函数,第二个括号表示马上执行第一个括号里面的代码。
首先明白,javascript里面是没有命名空间的,要保证你的javascript函数、对象与其他的不冲突,这里用了javascript的一个技巧:你的所有javascript函数、对象都在一个匿名函数里面定义,确保了所定义的函数、对象的有效范围,起到了命名空间的作用。既然作用范围在这个匿名函数中,怎么被别人使用呢?下面看它的下面代码:
首先明白,javascript里面是没有命名空间的,要保证你的javascript函数、对象与其他的不冲突,这里用了javascript的一个技巧:你的所有javascript函数、对象都在一个匿名函数里面定义,确保了所定义的函数、对象的有效范围,起到了命名空间的作用。既然作用范围在这个匿名函数中,怎么被别人使用呢?下面看它的下面代码:
var jQuery = window.jQuery = function(selector, context) {
//……
};
//……
};
这里让jQuery库中最重要的对象jQuery成为了window对象的一个属性,这样就可以在其他地方像使用document(document也是window的一个属性)一样使用jQuery了。也许使用过jQuery的朋友惊讶-我没有使用jQuery对象,一直使用$的。没错,那是jQuery的同名对象:
window.$ = jQuery;
现在明白了吧。
执行过程分析
jquery源码在线JavaScript是一门基于对象的语言,而它的对象技术的实现又和其他语言有着很大的差异,在JavaScript中,一个类的定义一般采用下面这种模式(我所看到的):
/
/ 定义一个构造函数;
testClass(param1, param2) {
this.attr1 = param1;
this.attr2 = param2;
...
}
// 在prototype对象上扩展,加上相应的方法;
testClass.prototype = {
Method1: function() {...},
Method2: function() {...},
...
}
// 定义一个实例;
var test = new testClass();
testClass(param1, param2) {
this.attr1 = param1;
this.attr2 = param2;
...
}
// 在prototype对象上扩展,加上相应的方法;
testClass.prototype = {
Method1: function() {...},
Method2: function() {...},
...
}
// 定义一个实例;
var test = new testClass();
在jQuery.js中,同样也是这种模式,只不过它要复杂很多,而且它还定义了一个d()的静态方法来扩展类的功能,jQuery.js代码执行过程完整分析如下:
// 防止多次载入而进行jQuery对象的判断;
if ( typeof window.jQuery == "undefined" ) {
window.undefined = window.undefined;
// jQuery的构造函数;
var jQuery = function( a, c ) { ... };
// jQuery的命名空间$;
if ( typeof $ != "undefined" ) jQuery._$ = $;
var $ = jQuery;
// 给jQuery的prototype增加一些基础方法和属性;
// 其中有些方法是调用下面的扩展方法实现的;
if ( typeof window.jQuery == "undefined" ) {
window.undefined = window.undefined;
// jQuery的构造函数;
var jQuery = function( a, c ) { ... };
// jQuery的命名空间$;
if ( typeof $ != "undefined" ) jQuery._$ = $;
var $ = jQuery;
// 给jQuery的prototype增加一些基础方法和属性;
// 其中有些方法是调用下面的扩展方法实现的;
// 注意下面的jQuery.fn = jQuery.prototype;
jQuery.fn = jQuery.prototype = {
each: function( fn, args ) { ... },
find: function( t ) { ... },
...
};
// jQuery实现继承的方法;
d = d = function( obj, prop ) {...};
// 实现一些基础的函数,有大部分是上面调用;
d({
init: function() { ... },
each: function( obj, fn, args ) { ... },
find: function( t, context ) { ... },
jQuery.fn = jQuery.prototype = {
each: function( fn, args ) { ... },
find: function( t ) { ... },
...
};
// jQuery实现继承的方法;
d = d = function( obj, prop ) {...};
// 实现一些基础的函数,有大部分是上面调用;
d({
init: function() { ... },
each: function( obj, fn, args ) { ... },
find: function( t, context ) { ... },
...
});
// 浏览器版本的检测;
new function() {
jQuery.browser = { safari:..., opera:..., msie:..., mozilla:... };
...
};
// jQuery.macros扩展,主要用于jQuery.init(),进行jQuery的初始化;
jQuery.macros = {
filter: [ ... ],
attr: { ... },
each: { ... },
...
});
// 浏览器版本的检测;
new function() {
jQuery.browser = { safari:..., opera:..., msie:..., mozilla:... };
...
};
// jQuery.macros扩展,主要用于jQuery.init(),进行jQuery的初始化;
jQuery.macros = {
filter: [ ... ],
attr: { ... },
each: { ... },
...
};
// jQuery初始化;
jQuery.init();
// 实现jQuery的重要方法ready();
d({
ready: function( f ) { ... }
...
};
// 上面ready()方法的具体实现;
d({
ready: function() { ... },
...
// jQuery初始化;
jQuery.init();
// 实现jQuery的重要方法ready();
d({
ready: function( f ) { ... }
...
};
// 上面ready()方法的具体实现;
d({
ready: function() { ... },
...
};
// 对浏览器某些事件进行绑定和解绑定;
new function() {
...
jQuery.event.add( window, "load", ady );
};
// 当IE浏览器关闭时,清除上面绑定的事件,防止内存泄漏;
if ( jQuery.browser.msie ) jQuery(window).unload( ... );
// 实现一些浏览器效果;
d({
show: function( speed, callback ) { ... },
hide: function( speed, callback ) { ... },
// 对浏览器某些事件进行绑定和解绑定;
new function() {
...
jQuery.event.add( window, "load", ady );
};
// 当IE浏览器关闭时,清除上面绑定的事件,防止内存泄漏;
if ( jQuery.browser.msie ) jQuery(window).unload( ... );
// 实现一些浏览器效果;
d({
show: function( speed, callback ) { ... },
hide: function( speed, callback ) { ... },
...
};
// 上面的一些函数具体实现;
d( {...} );
// 以下都是Ajax的实现,这里声明原型,具体实现调用下面的函数;
d({
loadIfModified: function(url, params, callback ) { ... },
...
};
// 针对IE浏览器创建不同的XMLHttpRequest对象;
if (jQuery.browser.msie && typeof XMLHttpRequest == "undefined") { ... };
};
// 上面的一些函数具体实现;
d( {...} );
// 以下都是Ajax的实现,这里声明原型,具体实现调用下面的函数;
d({
loadIfModified: function(url, params, callback ) { ... },
...
};
// 针对IE浏览器创建不同的XMLHttpRequest对象;
if (jQuery.browser.msie && typeof XMLHttpRequest == "undefined") { ... };
// Ajax函数的绑定;
new function() {
var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(",");
...
};
// Ajax函数的具体实现;
d({
get: function( url, data, callback, type, ifModified ) { ... },
post: function( url, data, callback, type ) { ... },
ajax: function( type, url, data, ret, ifModified ) { ... },
...
}
}
new function() {
var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(",");
...
};
// Ajax函数的具体实现;
d({
get: function( url, data, callback, type, ifModified ) { ... },
post: function( url, data, callback, type ) { ... },
ajax: function( type, url, data, ret, ifModified ) { ... },
...
}
}
构造函数详解
在jQuery.js的构造函数中,充分利用了JavsScript语言的动态性——对行参的类型和个数没有的严格要求,以至于一个函数可以实现多种功能需求,也为JavaScript语言的多态性提供了基础,在这个构造函数中,提供了六种不同的调用格式(根据官方API文档),具体如下($ = jQuery):
1、$(String expr):根据给定的CSS选择符查匹配的元素,如$("div>p");
2、$(Element elem):将给定的DOM元素对象转换为jQuery对象,如$(document).find("div>p");
3、$(Array<Element> elems):如$(myForm.elements).hide();
4、$(Function fn):是$(document).ready()的简写模式,如:$( function fn(){ ... } );
5、$(jQuery obj):如:var div = $("div"); $(div).find("p");
6、$(String expr, Element context):在context中查expr,如:$("div", sponseXML);
2、$(Element elem):将给定的DOM元素对象转换为jQuery对象,如$(document).find("div>p");
3、$(Array<Element> elems):如$(myForm.elements).hide();
4、$(Function fn):是$(document).ready()的简写模式,如:$( function fn(){ ... } );
5、$(jQuery obj):如:var div = $("div"); $(div).find("p");
6、$(String expr, Element context):在context中查expr,如:$("div", sponseXML);
另外,jQuery中提到了Chainable Methods的思想,也就是调用jQuery中的方法会返回一个jQuery对象,仍然可以继续调用其中的方法,这样,就形成了一个“链条”,通过“.”一个一个调用下去,这个在构造函数中有具体体现,其中有如下一条语句:
if( window == this ) return new jQuery( a, c );
这个就是为了返回一个jQuery对象,在首次调用jQuery( a, c )函数时,this是等于window的,所以每次都会创建一个jQuery对象,更详细的代码分析见下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论