作者:zccst
核心功能包括:
jQuery是如何定义的,如何调用的,如何扩展的。掌握核心方法是如何实现的,是理解jQuery源码的关键。这里理解了一切豁然开朗。
1,如何定义,即入口
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );//jQuery对象仅仅是构造函数jQuery.prototype.init加强版
}
2,jQuery的原型,及与jQuery.fn.init的关系
//定义对象方法,也即只有通过$("xx").的方式才能调用。
jQuery.fn = jQuery.prototype = {
init:function( selector, context, rootjQuery ) {
return jQuery.makeArray( selector, this );
}
其他还有很多属性和方法,
属性有:jquery,constructor, selector, length
方法有:toArray,get, pushStack,each, ready,slice, first,last,eq, map,end, push, sort, splice
...
}
//把jQuery.prototype赋给jQuery.prototype.init.prototype,是为了后面的实例化
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
也即是,$("xx")拥有了实例方法,可以调用。(调用jQuery.prototype下定义的方法)
3,extend扩展对象方法和静态方法原理
jQuery.extend = jQuery.fn.extend = function() {
var target = arguments[0] || {};
return target;
}
使用extend就方便了,无非就是$.extend({});和$.fn.extend({});如果你能在看到fn时理解联想到是jQuery.prototype就好了。
再通过this作用域看一下:
$.extend ->this是$-> this.aa()
$.fn.extend->this是$.fn-> this.aa()
附extend实现细节:
使用场景:
1,扩展一些函数
只有一个参数。例如:$.extend({f1:function(){},f2:function(){},f3:function(){}})
2,合并多个对象到第一个对象
(1)浅copy,第一个参数是目标对象。例如
var a = {name:"hello"}
var b = {age:30}
$.extend(a,b);//a={name:"hello",age:30}
(2)深copy,第一个参数是TRUE,第二个参数是目标对象。例如
var a = {name:{job:"it"}};
var b = {name:{age: 30 }};
//$.extend(a,b);
$.extend(true,a,b);
console.log(a);
1 jQuery.extend = jQuery.fn.extend = function() { 2 var options, name, src, copy, copyIsArray, clone, 3 target = arguments[0] || {}, 4 i = 1, 5 length = arguments.length, 6 deep = false; 7 8 // 是不是深复制 Handle a deep copy situation 9 if ( typeof target === "boolean" ) { 10 deep = target; 11 target = arguments[1] || {}; 12 // skip the boolean and the target 13 i = 2; 14 } 15 16 // 不是对象类型 Handle case when target is a string or something (possible in deep copy) 17 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 18 target = {}; 19 } 20 21 // 扩展插件的情况 extend jQuery itself if only one argument is passed 22 if ( length === i ) {//$.extend({f1:function(){},f2:function(){},f3:function(){}}) 23 target = this;//this是$,或是$.fn 24 --i; 25 } 26 27 for ( ; i < length; i++ ) {//可能有多个对象扩展到第一个对象上 28 // Only deal with non-null/undefined values 29 if ( (options = arguments[ i ]) != null ) {//options是一个对象 30 // Extend the base object 31 for ( name in options ) { 32 src = target[ name ]; //src是target里已经存在的value(也可能不存在) 33 copy = options[ name ];//copy是待合入的一个value 34 35 // 防止循环引用 Prevent never-ending loop 36 if ( target === copy ) {//例如:var a={};$.extend(a,{name:a});//可能导致循环引用 37 continue; 38 } 39 40 // if是深复制else是浅复制 Recurse if we're merging plain objects or arrays 41 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 42 if ( copyIsArray ) { 43 copyIsArray = false; 44 clone = src && jQuery.isArray(src) ? src : []; 45 46 } else { 47 clone = src && jQuery.isPlainObject(src) ? src : {}; 48 } 49 50 // 亮了,直至剥离至最深一层非对象类型,而且是逐个。Never move original objects, clone them 51 target[ name ] = jQuery.extend( deep, clone, copy ); 52 53 // Don't bring in undefined values 54 } else if ( copy !== undefined ) { 55 target[ name ] = copy;//target[ name ] = options[ name ]; 56 } 57 } 58 } 59 } 60 61 // Return the modified object 62 return target; 63 };