jQuery 源码分析4: jQuery.extend
jQuery.extend是jQuery最重要的方法之一,下面看看jQuery是怎样实现扩展操作的
1 // 如果传入一个对象,这个对象的属性会被添加到jQuery对象中 2 3 // 如果传入两个或多个对象,所有对象的属性会被添加到第一个对象中 4 5 // 如果想合并两个对象,则可以这样用: $.extend({}, obj1, obj2); 6 7 // 如果第一个参数是true,则执行深拷贝(迭代合并) 8 9 10 11 jQuery.extend = jQuery.fn.extend = function() { 12 var src, copyIsArray, copy, name, options, clone, 13 target = arguments[0] || {}, // 获取第一个参数,第1个参数选择是否进行深拷贝 14 i = 1, 15 length = arguments.length, 16 deep = false; 17 18 // 处理深拷贝 19 if ( typeof target === "boolean" ) { 20 deep = target; 21 // 跳过第一个boolean值 22 target = arguments[ i ] || {}; // i == 1 23 i++; 24 } 25 26 27 28 // 如果target是一个非object且非function (是string或其他类型,可能要深拷贝) 29 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 30 target = {}; 31 } 32 33 // 如果只有一个参数,则扩展jQuery对象自己 34 if ( i === length ) { 35 target = this; 36 i--; 37 } 38 for ( ; i < length; i++ ) { 39 // 只处理非null或undefined的值 40 if ( (options = arguments[ i ]) != null ) { 41 // 开始扩展基类对象 42 for ( name in options ) { 43 src = target[ name ]; 44 copy = options[ name ]; 45 // 防止一个环形链,造成循环引用 46 if ( target === copy ) { 47 continue; 48 } 49 // 如果要执行纯对象的深拷贝或拷贝Array时,要递归jQuery.extend 50 51 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 52 if ( copyIsArray ) { 53 copyIsArray = false; 54 55 // 确保src是一个数组 56 clone = src && jQuery.isArray(src) ? src : []; 57 } else { 58 59 // 确保src是一个纯对象 60 clone = src && jQuery.isPlainObject(src) ? src : {}; 61 } 62 // 递归调用jQuery.extend来实现深拷贝 63 target[ name ] = jQuery.extend( deep, clone, copy ); 64 65 // 丢弃undefined值 66 } else if ( copy !== undefined ) { 67 // 执行拷贝 68 69 target[ name ] = copy; 70 } 71 } 72 } 73 } 74 // 返回扩展后的对象 75 return target; 76 };
通过jQuery.extend方法可以为jQuery或其他对象进行属性扩展操作。对于纯对象可选择执行深拷贝,对于数组是一定执行深拷贝。
jQuery的大部分功能都通过此方法进行扩展,也可以此为jQuery扩展插件。
jQuery.extend({}),此时target为 jQuery.prototype,为jQuery扩展静态属性或方法,jQuery内部也是以此方法进行。
jQuery().extend({}),此时target为jQuery对象本身,给jQuery对象扩展属性或方法。