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赋值给deep20 ??// deep表示是否进行深层面的复制,当为true时,进行深度复制,否则只进行第一层扩展21 ??// 然后把第二个参数赋值给target22 ??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.fn37 ????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() 源码分析
原文地址:https://www.cnblogs.com/liuzhaoxu/p/8977748.html