jQuery.extend() 源码分析

 jQuery.extend() 方法

  1. 可以合并对象
  2. 深拷贝与浅拷贝

源码分析:

 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 };

猜你喜欢

转载自www.cnblogs.com/liuzhaoxu/p/8977748.html