jQuery.extend() 源码分析
Posted liuzhaoxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jQuery.extend() 源码分析相关的知识,希望对你有一定的参考价值。
jQuery.extend() 方法
- 可以合并对象
- 深拷贝与浅拷贝
源码分析:
概述: 1. 首先定义变量
options:保存每次循环遍历的arguments[i] ,
name: 保存循环遍历对象的key值
src:保存目标对象target的属性
copy: 保存合并对象的属性
copyIsArray: 如果copy是数组,用copyIsArray保存
clone:如果目标对象是数组,用clone保存。
target:目标对象
deep: boolean值,判断是否是深拷贝
2. 然后判断是否是深拷贝,如果是deep值变为target,i的值变为2,跳过前两个参数。
3. 判断target是不是一个对象或者函数,如果都不是,就把target变为一个空对象
4. 判断是否只有一个参数的情况
5. 遍历需要被扩展target的参数,判断deep是否是true,如果是,就利用递归开始深克隆,如果不是就浅克隆
6. 如果是浅克隆,就直接把copy的值赋给target[name]。
注意:不支持第一个参数写false,如果是浅拷贝就不要写。
1 // extend方法为jQuery对象和init对象的prototype扩展方法 2 // 同时具有独立的扩展普通对象的功能 3 jQuery.extend = jQuery.fn.extend = function() { 4 /* 5 *target被扩展的对象 6 *length参数的数量 7 *deep是否深度操作 8 */ 9 var options, 10 name, 11 src, 12 copy, 13 copyIsArray, 14 clone, 15 target = arguments[0] || {}, 16 i = 1, 17 length = arguments.length, 18 deep = false; 19 // target为第一个参数,如果第一个参数是Boolean类型的值,则把target赋值给deep 20 // deep表示是否进行深层面的复制,当为true时,进行深度复制,否则只进行第一层扩展 21 // 然后把第二个参数赋值给target 22 if (typeof target === ‘boolean‘) { 23 deep = target; 24 target = arguments[1] || {}; 25 // 将i赋值为2,跳过前两个参数 26 i = 2; 27 } 28 // target既不是对象也不是函数则把target设置为空对象。 29 if (typeof target !== ‘object‘ && !jQuery.isFunction(target)) { 30 target = {}; 31 } 32 // 如果只有一个参数,则把jQuery对象赋值给target,即扩展到jQuery对象上 33 // extend(true, {}); 34 // extend(obj); 35 if (length === i) { 36 // this ==> jQuery/jQuery.fn 37 target = this; 38 // 如果i=2, --i是为了让循环从1开始,如果i=1, --i是为了让循环从0开始 39 --i; 40 } 41 // 开始遍历需要被扩展到target上的参数 42 for (; i < length; i++) { 43 // 处理第i个被扩展的对象,即除去deep和target之外的对象 44 if ((options = arguments[i]) != null) { 45 // 遍历第i个对象的所有可遍历的属性 46 for (name in options) { 47 // 用src保存目标对象的属性 48 src = target[name]; 49 // 用copy保存合并对象的属性 50 copy = options[name]; 51 // 如果两个属性相等,就不用合并了 52 if (target === copy) { 53 continue; 54 } 55 // 当用户想要深度操作时,递归合并 56 // copy是纯对象或者是数组 57 if ( 58 deep && 59 copy && 60 (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy))) 61 ) { 62 // 如果是数组 63 if (copyIsArray) { 64 // 将copyIsArray重新设置为false,为下次遍历做准备。 65 copyIsArray = false; 66 // 判断被扩展的对象中src是不是数组 67 clone = src && jQuery.isArray(src) ? src : []; 68 } else { 69 // 判断被扩展的对象中src是不是纯对象 70 clone = src && jQuery.isPlainObject(src) ? src : {}; 71 } 72 // 递归调用extend方法,继续进行深度遍历 73 target[name] = jQuery.extend(deep, clone, copy); 74 } 75 // 如果不需要深度复制,则直接把copy(第i个被扩展对象中被遍历的那个键的值) 76 else if (copy !== undefined) { 77 target[name] = copy; 78 } 79 } 80 } 81 } 82 // 原对象被改变,因此如果不想改变原对象,target可传入{} 83 return target; 84 };
示例:
如果要合并以上两个对象
需要一下6步
以上是关于jQuery.extend() 源码分析的主要内容,如果未能解决你的问题,请参考以下文章