本人在很久之前已经很想细读jQuery的源码了,可是一直没这个勇气去看,现在有时间了,看了一些大神的博客还有看了一本Nicholas C.Zakas的JavaScript高级程序设计(第3版)的书,感觉自己信心增强了不少,站在巨人的肩膀上,自己将可以站得更高,看得更远。
源码解析是一条漫长而艰辛的道路,一个人走是很难走下去的,只有不断思考和借鉴大神们的思想和经验,才能在这条道路上走得更远。Coco大神的博客文章【深入浅出jQuery】源码浅析–整体架构带我走进了jQuery源码解析的大门。以前api就看的多了,使用起来也没什么障碍,可是真正要弄懂这些方法实现的原理,就没那么简单了。但是一旦弄懂原理之后,就会发现:哦,框架原来是这样构成的!
网上关于jQuery源码解析的文章多不胜数,我写的解析可能比很多大神都不够深入或者不够详尽。但是写文章要清楚首先是写给自己看的,其次才是分享。将自己所见所闻的知识通过自己的理解再写出来,可以达到另一种高度,除了加深对知识的理解外,还可以让别人来评价一下自己的理解,纠正自己的错误。
我感觉如果要做源码解析的话,方法应该是这样的:阅读API -> 浏览别人的博客 -> 阅读源码 -> 测试源码片段 -> 重新阅读别人的博客 -> 撰写自己的博客 -> 自己尝试写一遍源码
本人将会持续更新关于jQuery源码解析的文章,现在暂时写的3个部分的内容,跳转回原页面代表该篇章尚未撰写。大家可以在评论区下留言,有什么不足或者错误的地方都可以提出来,小弟感激不尽。
// 兼容AMD规范
14 ( function( global, factory ) {
"use strict";
....
40 })( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
....
return jQuery;
10220 });
// jQuery初始化
"use strict";
94 var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
99 };
114 jQuery.fn = jQuery.prototype = {
119 constructor: jQuery
....
193 };
2959 init = jQuery.fn.init = function( selector, context, root ) {
....
3056 };
3059 init.prototype = jQuery.fn;
// jQuery插件拓展
195 jQuery.extend = jQuery.fn.extend = function() {
....
return target;
262 }
// jQuery工具(静态方法)$.fn
264 jQuery.extend( {
error: xxx,
noop: xxx,
isFunction: xxx,
each: xxx,
makeArray: xxx,
....
516 } );
// 复杂选择器Sizzle
544 var Sizzle = (function( window ) {
760 function Sizzle( selector, context, results, seed ) {
....
return select( selector.replace( rtrim, "$1" ), context, results, seed );
891 }
....
return Sizzle;
2797 })( window );
// $.ready() & $().ready()
3863 var readyList = jQuery.Deferred();
3865 jQuery.fn.ready = function( fn ) {
....
return this;
3878 }
3899 jQuery.extend( {
ready: function( wait ) {
....
3916 }
3917 } );
// 回调对象$.Callback()
3262 jQuery.Callbacks = function( options ) {
3337 self = {
add: xxx,
remove: xxx
has: xxx,
....
3450 }
return self;
3454 }
// 延迟对象$.Deferred()
jQuery.extend( {
3498 Deferred: function( func ) {
3511 promise = {};
3776 promise.promise( deferred );
....
return deferred;
3785 }
3788 when: function( singleValue ) {
return jQuery.Deferred().promise();
3833 }
} );
// 浏览器功能性检测$.support
3841 jQuery.Deferred.exceptionHook = function( error, stack ) {
// Support: IE 8 - 9 only
....
3848 }
3930 // Support: IE <=9 - 10 only
4185 // Support: Chrome <=35 - 45
4280 // Support: IE 11 only
4776 // Support: Android <=4.0 only, PhantomJS 1 only
.... other supports
// 数据存储$.data & $().data
4024 function Data() { this.expando = jQuery.expando + Data.uid++; }
4030 Data.prototype = {
....
4173 };
4241 jQuery.extend( {
hasData: xxx,
data: xxx,
removeData: xxx,
_data: xxx,
_removeData: xxx
} );
jQuery.fn.extend( {
4266 data: function( key, value ) {
return access(this, function( value ) { .... }, null, value, arguments.length > 1, null, true );
4339 },
4341 removeData: function( key ) {
return xxx;
4345 }
} );
// 队列方法queue() & dequeue()
jQuery.extend( {
4530 queue: function( elem, type, data ) {
return dataPriv.get( elem, type ) || [];
4367 },
4369 dequeue: function( elem, type ) {
....
4402 },
4405 _queueHooks: function( elem, type ) {
....
4412 }
} );
jQuery.fn.extend( {
4416 queue: function( type, data ) {
return xxx;
4441 },
4442 dequeue: function( type ) {
return xxx;
4446 },
4447 clearQueue: function( type ) {
return xxx;
4449 },
4453 promise: function( type, obj ) {
return defer.promise( obj );
4480 }
} );
// 对元素属性的操作
7456 jQuery.fn.extend( {
attr: xxx, removeAttr: xxx
7466 } );
7588 jQuery.fn.extend( {
prop: xxx, removeProp: xxx
7598 } );
jQuery.fn.extend....
// 事件操作
4965 jQuery.event = {
....
5366 };
5376 jQuery.Event = function( src, props ) {
....
5423 };
5427 jQuery.Event.prototype = {
constructor: jQuery.Event,
....
5463 };
5562 jQuery.fn.extend( {
on: xxx, one: xxx, off: xxx
5606 } );
// DOM操作
5896 jQuery.fn.extend( {
detach: xxx, remove: xxx, text: xxx, append: xxx, prepend: xxx, before: xxx, after: xxx, empty: xxx
6034 } );
jQuery.fn.extend....
// css操作
jQuery.extend( {
6376 cssHooks: {},
6413 style: function( elem, name, value, extra ) {},
6479 css: function( elem, name, extra, styles ) {}
} );
// $.ajax()
jQuery.extend( {
8834 ajax: function( url, options ) {
....
8971 deferred.promise( jqXHR );
....
9270 }
} );
// 动画animate()
jQuery.fn.extend( {
7217 animate: function( prop, speed, easing, callback ) {}
} );
// 多库共存noConflict()
10191 var _jQuery = window.jQuery,
_$ = window.$;
10196 jQuery.noConflict = function( deep ) {
return jQuery;
10206 }
// 最后将jQuery暴露出去
10211 if ( !noGlobal ) {
window.jQuery = window.$ = jQuery;
}